// Copyright 2015 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 "net/ssl/ssl_client_session_cache.h"

#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/simple_test_clock.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/traced_value.h"
#include "net/base/network_isolation_key.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
#include "url/gurl.h"

using testing::ByRef;
using testing::Contains;
using testing::Eq;
using testing::Field;

namespace net {

namespace {

std::unique_ptr<base::SimpleTestClock> MakeTestClock() {
  std::unique_ptr<base::SimpleTestClock> clock =
      std::make_unique<base::SimpleTestClock>();
  // SimpleTestClock starts at the null base::Time which converts to and from
  // time_t confusingly.
  clock->SetNow(base::Time::FromTimeT(1000000000));
  return clock;
}

SSLClientSessionCache::Key MakeTestKey(const std::string& str) {
  SSLClientSessionCache::Key key;
  key.server = HostPortPair(str, 443);
  return key;
}

class SSLClientSessionCacheTest : public testing::Test {
 public:
  SSLClientSessionCacheTest() : ssl_ctx_(SSL_CTX_new(TLS_method())) {}

 protected:
  bssl::UniquePtr<SSL_SESSION> NewSSLSession(
      uint16_t version = TLS1_2_VERSION) {
    SSL_SESSION* session = SSL_SESSION_new(ssl_ctx_.get());
    if (!SSL_SESSION_set_protocol_version(session, version))
      return nullptr;
    return bssl::UniquePtr<SSL_SESSION>(session);
  }

  bssl::UniquePtr<SSL_SESSION> MakeTestSession(base::Time now,
                                               base::TimeDelta timeout) {
    bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();
    SSL_SESSION_set_time(session.get(), now.ToTimeT());
    SSL_SESSION_set_timeout(session.get(), timeout.InSeconds());
    return session;
  }

 private:
  bssl::UniquePtr<SSL_CTX> ssl_ctx_;
};

}  // namespace

// These tests rely on memory corruption detectors to verify that
// SSL_SESSION reference counts were correctly managed and no sessions
// leaked or were accessed after free.

// Test basic insertion and lookup operations.
TEST_F(SSLClientSessionCacheTest, Basic) {
  SSLClientSessionCache::Config config;
  SSLClientSessionCache cache(config);

  bssl::UniquePtr<SSL_SESSION> session1 = NewSSLSession();
  bssl::UniquePtr<SSL_SESSION> session2 = NewSSLSession();
  bssl::UniquePtr<SSL_SESSION> session3 = NewSSLSession();

  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(0u, cache.size());

  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(1u, cache.size());

  cache.Insert(MakeTestKey("key2"), bssl::UpRef(session2));
  EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(2u, cache.size());

  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session3));
  EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(2u, cache.size());

  cache.Flush();
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key3")).get());
  EXPECT_EQ(0u, cache.size());
}

// Test basic insertion and lookup operations with single-use sessions.
TEST_F(SSLClientSessionCacheTest, BasicSingleUse) {
  SSLClientSessionCache::Config config;
  SSLClientSessionCache cache(config);

  bssl::UniquePtr<SSL_SESSION> session1 = NewSSLSession(TLS1_3_VERSION);
  bssl::UniquePtr<SSL_SESSION> session2 = NewSSLSession(TLS1_3_VERSION);
  bssl::UniquePtr<SSL_SESSION> session3 = NewSSLSession(TLS1_3_VERSION);

  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(0u, cache.size());

  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(0u, cache.size());

  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());

  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  cache.Insert(MakeTestKey("key2"), bssl::UpRef(session2));

  EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(1u, cache.size());

  EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());

  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session3));
  cache.Insert(MakeTestKey("key2"), bssl::UpRef(session2));
  EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(0u, cache.size());

  cache.Flush();
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key3")).get());
  EXPECT_EQ(0u, cache.size());

  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session2));
  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session3));
  EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
}

// Test insertion and lookup operations with both single-use and reusable
// sessions.
TEST_F(SSLClientSessionCacheTest, MixedUse) {
  SSLClientSessionCache::Config config;
  SSLClientSessionCache cache(config);

  bssl::UniquePtr<SSL_SESSION> session_single = NewSSLSession(TLS1_3_VERSION);
  bssl::UniquePtr<SSL_SESSION> session_reuse = NewSSLSession(TLS1_2_VERSION);

  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(0u, cache.size());

  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session_reuse));
  EXPECT_EQ(session_reuse.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(1u, cache.size());

  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session_single));
  EXPECT_EQ(session_single.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(0u, cache.size());

  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(0u, cache.size());

  cache.Insert(MakeTestKey("key2"), bssl::UpRef(session_single));
  cache.Insert(MakeTestKey("key2"), bssl::UpRef(session_single));
  EXPECT_EQ(1u, cache.size());

  EXPECT_EQ(session_single.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(session_single.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(0u, cache.size());

  cache.Insert(MakeTestKey("key2"), bssl::UpRef(session_single));
  cache.Insert(MakeTestKey("key2"), bssl::UpRef(session_reuse));
  EXPECT_EQ(session_reuse.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(session_reuse.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(1u, cache.size());
}

// Test that a session may be inserted at two different keys. This should never
// be necessary, but the API doesn't prohibit it.
TEST_F(SSLClientSessionCacheTest, DoubleInsert) {
  SSLClientSessionCache::Config config;
  SSLClientSessionCache cache(config);

  bssl::UniquePtr<SSL_SESSION> session = NewSSLSession();

  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(0u, cache.size());

  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session));
  EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(1u, cache.size());

  cache.Insert(MakeTestKey("key2"), bssl::UpRef(session));
  EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(2u, cache.size());

  cache.Flush();
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(0u, cache.size());
}

// Tests that the session cache's size is correctly bounded.
TEST_F(SSLClientSessionCacheTest, MaxEntries) {
  SSLClientSessionCache::Config config;
  config.max_entries = 3;
  SSLClientSessionCache cache(config);

  bssl::UniquePtr<SSL_SESSION> session1 = NewSSLSession();
  bssl::UniquePtr<SSL_SESSION> session2 = NewSSLSession();
  bssl::UniquePtr<SSL_SESSION> session3 = NewSSLSession();
  bssl::UniquePtr<SSL_SESSION> session4 = NewSSLSession();

  // Insert three entries.
  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  cache.Insert(MakeTestKey("key2"), bssl::UpRef(session2));
  cache.Insert(MakeTestKey("key3"), bssl::UpRef(session3));
  EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key3")).get());
  EXPECT_EQ(3u, cache.size());

  // On insertion of a fourth, the first is removed.
  cache.Insert(MakeTestKey("key4"), bssl::UpRef(session4));
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(session4.get(), cache.Lookup(MakeTestKey("key4")).get());
  EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key3")).get());
  EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(3u, cache.size());

  // Despite being newest, the next to be removed is session4 as it was accessed
  // least. recently.
  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key3")).get());
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key4")).get());
  EXPECT_EQ(3u, cache.size());
}

// Tests that session expiration works properly.
TEST_F(SSLClientSessionCacheTest, Expiration) {
  const size_t kNumEntries = 20;
  const size_t kExpirationCheckCount = 10;
  const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(1000);

  SSLClientSessionCache::Config config;
  config.expiration_check_count = kExpirationCheckCount;
  SSLClientSessionCache cache(config);
  std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
  cache.SetClockForTesting(clock.get());

  // Add |kNumEntries - 1| entries.
  for (size_t i = 0; i < kNumEntries - 1; i++) {
    bssl::UniquePtr<SSL_SESSION> session =
        MakeTestSession(clock->Now(), kTimeout);
    cache.Insert(MakeTestKey(base::NumberToString(i)), bssl::UpRef(session));
  }
  EXPECT_EQ(kNumEntries - 1, cache.size());

  // Expire all the previous entries and insert one more entry.
  clock->Advance(kTimeout * 2);
  bssl::UniquePtr<SSL_SESSION> session =
      MakeTestSession(clock->Now(), kTimeout);
  cache.Insert(MakeTestKey("key"), bssl::UpRef(session));

  // All entries are still in the cache.
  EXPECT_EQ(kNumEntries, cache.size());

  // Perform one fewer lookup than needed to trigger the expiration check. This
  // shall not expire any session.
  for (size_t i = 0; i < kExpirationCheckCount - 1; i++)
    cache.Lookup(MakeTestKey("key"));

  // All entries are still in the cache.
  EXPECT_EQ(kNumEntries, cache.size());

  // Perform one more lookup. This will expire all sessions but the last one.
  cache.Lookup(MakeTestKey("key"));
  EXPECT_EQ(1u, cache.size());
  EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key")).get());
  for (size_t i = 0; i < kNumEntries - 1; i++) {
    SCOPED_TRACE(i);
    EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey(base::NumberToString(i))));
  }
}

// Tests that Lookup performs an expiration check before returning a cached
// session.
TEST_F(SSLClientSessionCacheTest, LookupExpirationCheck) {
  // kExpirationCheckCount is set to a suitably large number so the automated
  // pruning never triggers.
  const size_t kExpirationCheckCount = 1000;
  const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(1000);

  SSLClientSessionCache::Config config;
  config.expiration_check_count = kExpirationCheckCount;
  SSLClientSessionCache cache(config);
  std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
  cache.SetClockForTesting(clock.get());

  // Insert an entry into the session cache.
  bssl::UniquePtr<SSL_SESSION> session =
      MakeTestSession(clock->Now(), kTimeout);
  cache.Insert(MakeTestKey("key"), bssl::UpRef(session));
  EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key")).get());
  EXPECT_EQ(1u, cache.size());

  // Expire the session.
  clock->Advance(kTimeout * 2);

  // The entry has not been removed yet.
  EXPECT_EQ(1u, cache.size());

  // But it will not be returned on lookup and gets pruned at that point.
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key")).get());
  EXPECT_EQ(0u, cache.size());

  // Re-inserting a session does not refresh the lifetime. The expiration
  // information in the session is used.
  cache.Insert(MakeTestKey("key"), bssl::UpRef(session));
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key")).get());
  EXPECT_EQ(0u, cache.size());

  // Re-insert a fresh copy of the session.
  session = MakeTestSession(clock->Now(), kTimeout);
  cache.Insert(MakeTestKey("key"), bssl::UpRef(session));
  EXPECT_EQ(session.get(), cache.Lookup(MakeTestKey("key")).get());
  EXPECT_EQ(1u, cache.size());

  // Sessions also are treated as expired if the clock rewinds.
  clock->Advance(base::TimeDelta::FromSeconds(-2));
  EXPECT_EQ(nullptr, cache.Lookup(MakeTestKey("key")).get());
  EXPECT_EQ(0u, cache.size());
}

// Test that SSL cache is flushed on low memory notifications
TEST_F(SSLClientSessionCacheTest, TestFlushOnMemoryNotifications) {
  base::test::TaskEnvironment task_environment;

  // kExpirationCheckCount is set to a suitably large number so the automated
  // pruning never triggers.
  const size_t kExpirationCheckCount = 1000;
  const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(1000);

  SSLClientSessionCache::Config config;
  config.expiration_check_count = kExpirationCheckCount;
  SSLClientSessionCache cache(config);
  std::unique_ptr<base::SimpleTestClock> clock = MakeTestClock();
  cache.SetClockForTesting(clock.get());

  // Insert an entry into the session cache.
  bssl::UniquePtr<SSL_SESSION> session1 =
      MakeTestSession(clock->Now(), kTimeout);
  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(1u, cache.size());

  // Expire the session.
  clock->Advance(kTimeout * 2);
  // Add one more session.
  bssl::UniquePtr<SSL_SESSION> session2 =
      MakeTestSession(clock->Now(), kTimeout);
  cache.Insert(MakeTestKey("key2"), bssl::UpRef(session2));
  EXPECT_EQ(2u, cache.size());

  // Fire a notification that will flush expired sessions.
  base::MemoryPressureListener::NotifyMemoryPressure(
      base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
  base::RunLoop().RunUntilIdle();

  // Expired session's cache should be flushed.
  // Lookup returns nullptr, when cache entry not found.
  EXPECT_FALSE(cache.Lookup(MakeTestKey("key1")));
  EXPECT_TRUE(cache.Lookup(MakeTestKey("key2")));
  EXPECT_EQ(1u, cache.size());

  // Fire notification that will flush everything.
  base::MemoryPressureListener::NotifyMemoryPressure(
      base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0u, cache.size());
}

TEST_F(SSLClientSessionCacheTest, FlushForServer) {
  SSLClientSessionCache::Config config;
  SSLClientSessionCache cache(config);

  const url::Origin kOriginA = url::Origin::Create(GURL("https://a.test"));
  const url::Origin kOriginB = url::Origin::Create(GURL("https://b.test"));

  // Insert a number of cache entries.
  SSLClientSessionCache::Key key1;
  key1.server = HostPortPair("a.test", 443);
  auto session1 = NewSSLSession();
  cache.Insert(key1, bssl::UpRef(session1));

  SSLClientSessionCache::Key key2;
  key2.server = HostPortPair("a.test", 443);
  key2.dest_ip_addr = IPAddress::IPv4Localhost();
  key2.network_isolation_key = NetworkIsolationKey(kOriginB, kOriginB);
  key2.privacy_mode = PRIVACY_MODE_ENABLED;
  auto session2 = NewSSLSession();
  cache.Insert(key2, bssl::UpRef(session2));

  SSLClientSessionCache::Key key3;
  key3.server = HostPortPair("a.test", 444);
  auto session3 = NewSSLSession();
  cache.Insert(key3, bssl::UpRef(session3));

  SSLClientSessionCache::Key key4;
  key4.server = HostPortPair("b.test", 443);
  auto session4 = NewSSLSession();
  cache.Insert(key4, bssl::UpRef(session4));

  SSLClientSessionCache::Key key5;
  key5.server = HostPortPair("b.test", 443);
  key5.network_isolation_key = NetworkIsolationKey(kOriginA, kOriginA);
  auto session5 = NewSSLSession();
  cache.Insert(key5, bssl::UpRef(session5));

  // Flush an unrelated server. The cache should be unaffected.
  cache.FlushForServer(HostPortPair("c.test", 443));
  EXPECT_EQ(5u, cache.size());
  EXPECT_EQ(session1.get(), cache.Lookup(key1).get());
  EXPECT_EQ(session2.get(), cache.Lookup(key2).get());
  EXPECT_EQ(session3.get(), cache.Lookup(key3).get());
  EXPECT_EQ(session4.get(), cache.Lookup(key4).get());
  EXPECT_EQ(session5.get(), cache.Lookup(key5).get());

  // Flush a.test:443. |key1| and |key2| should match, but not the others.
  cache.FlushForServer(HostPortPair("a.test", 443));
  EXPECT_EQ(3u, cache.size());
  EXPECT_EQ(nullptr, cache.Lookup(key1).get());
  EXPECT_EQ(nullptr, cache.Lookup(key2).get());
  EXPECT_EQ(session3.get(), cache.Lookup(key3).get());
  EXPECT_EQ(session4.get(), cache.Lookup(key4).get());
  EXPECT_EQ(session5.get(), cache.Lookup(key5).get());

  // Flush b.test:443. |key4| and |key5| match, but not |key3|.
  cache.FlushForServer(HostPortPair("b.test", 443));
  EXPECT_EQ(1u, cache.size());
  EXPECT_EQ(nullptr, cache.Lookup(key1).get());
  EXPECT_EQ(nullptr, cache.Lookup(key2).get());
  EXPECT_EQ(session3.get(), cache.Lookup(key3).get());
  EXPECT_EQ(nullptr, cache.Lookup(key4).get());
  EXPECT_EQ(nullptr, cache.Lookup(key5).get());

  // Flush the last host, a.test:444.
  cache.FlushForServer(HostPortPair("a.test", 444));
  EXPECT_EQ(0u, cache.size());
  EXPECT_EQ(nullptr, cache.Lookup(key1).get());
  EXPECT_EQ(nullptr, cache.Lookup(key2).get());
  EXPECT_EQ(nullptr, cache.Lookup(key3).get());
  EXPECT_EQ(nullptr, cache.Lookup(key4).get());
  EXPECT_EQ(nullptr, cache.Lookup(key5).get());
}

class SSLClientSessionCacheMemoryDumpTest
    : public SSLClientSessionCacheTest,
      public testing::WithParamInterface<
          base::trace_event::MemoryDumpLevelOfDetail> {};

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    SSLClientSessionCacheMemoryDumpTest,
    ::testing::Values(base::trace_event::MemoryDumpLevelOfDetail::DETAILED,
                      base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND));

// Basic test for dumping memory stats.
TEST_P(SSLClientSessionCacheMemoryDumpTest, TestDumpMemoryStats) {
  SSLClientSessionCache::Config config;
  SSLClientSessionCache cache(config);

  bssl::UniquePtr<SSL_SESSION> session1 = NewSSLSession();
  bssl::UniquePtr<SSL_SESSION> session2 = NewSSLSession();
  bssl::UniquePtr<SSL_SESSION> session3 = NewSSLSession();

  // Insert three entries.
  cache.Insert(MakeTestKey("key1"), bssl::UpRef(session1));
  cache.Insert(MakeTestKey("key2"), bssl::UpRef(session2));
  cache.Insert(MakeTestKey("key3"), bssl::UpRef(session3));
  EXPECT_EQ(session1.get(), cache.Lookup(MakeTestKey("key1")).get());
  EXPECT_EQ(session2.get(), cache.Lookup(MakeTestKey("key2")).get());
  EXPECT_EQ(session3.get(), cache.Lookup(MakeTestKey("key3")).get());
  EXPECT_EQ(3u, cache.size());

  base::trace_event::MemoryDumpArgs dump_args = {GetParam()};
  std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
      new base::trace_event::ProcessMemoryDump(dump_args));

  const std::string parent_absolute_name =
      "net/http_network_session_0xdeadbeef";
  const std::string expected_dump_name =
      parent_absolute_name + "/ssl_client_session_cache";

  cache.DumpMemoryStats(process_memory_dump.get(), parent_absolute_name);

  using Entry = base::trace_event::MemoryAllocatorDump::Entry;
  const base::trace_event::MemoryAllocatorDump* dump =
      process_memory_dump->GetAllocatorDump(expected_dump_name);
  ASSERT_NE(nullptr, dump);
  const std::vector<Entry>& entries = dump->entries();
  EXPECT_THAT(entries, Contains(Field(&Entry::name, Eq("cert_count"))));
  EXPECT_THAT(entries, Contains(Field(&Entry::name, Eq("cert_size"))));
  EXPECT_THAT(entries,
              Contains(Field(&Entry::name, Eq("undeduped_cert_size"))));
  EXPECT_THAT(entries,
              Contains(Field(&Entry::name, Eq("undeduped_cert_count"))));
  EXPECT_THAT(
      entries,
      Contains(Field(&Entry::name,
                     Eq(base::trace_event::MemoryAllocatorDump::kNameSize))));
}

}  // namespace net
