Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / ssl / ssl_client_session_cache_openssl_unittest.cc
blob7d8799ae9991a5f448e1f553857847f25a6d4dcb
1 // Copyright 2015 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.
5 #include "net/ssl/ssl_client_session_cache_openssl.h"
7 #include <openssl/ssl.h>
9 #include "base/strings/string_number_conversions.h"
10 #include "base/test/simple_test_clock.h"
11 #include "net/ssl/scoped_openssl_types.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 namespace net {
16 // Test basic insertion and lookup operations.
17 TEST(SSLClientSessionCacheOpenSSLTest, Basic) {
18 SSLClientSessionCacheOpenSSL::Config config;
19 SSLClientSessionCacheOpenSSL cache(config);
21 ScopedSSL_SESSION session1(SSL_SESSION_new());
22 ScopedSSL_SESSION session2(SSL_SESSION_new());
23 ScopedSSL_SESSION session3(SSL_SESSION_new());
24 EXPECT_EQ(1u, session1->references);
25 EXPECT_EQ(1u, session2->references);
26 EXPECT_EQ(1u, session3->references);
28 EXPECT_EQ(nullptr, cache.Lookup("key1"));
29 EXPECT_EQ(nullptr, cache.Lookup("key2"));
30 EXPECT_EQ(0u, cache.size());
32 cache.Insert("key1", session1.get());
33 EXPECT_EQ(session1.get(), cache.Lookup("key1"));
34 EXPECT_EQ(nullptr, cache.Lookup("key2"));
35 EXPECT_EQ(1u, cache.size());
37 cache.Insert("key2", session2.get());
38 EXPECT_EQ(session1.get(), cache.Lookup("key1"));
39 EXPECT_EQ(session2.get(), cache.Lookup("key2"));
40 EXPECT_EQ(2u, cache.size());
42 EXPECT_EQ(2u, session1->references);
43 EXPECT_EQ(2u, session2->references);
45 cache.Insert("key1", session3.get());
46 EXPECT_EQ(session3.get(), cache.Lookup("key1"));
47 EXPECT_EQ(session2.get(), cache.Lookup("key2"));
48 EXPECT_EQ(2u, cache.size());
50 EXPECT_EQ(1u, session1->references);
51 EXPECT_EQ(2u, session2->references);
52 EXPECT_EQ(2u, session3->references);
54 cache.Flush();
55 EXPECT_EQ(nullptr, cache.Lookup("key1"));
56 EXPECT_EQ(nullptr, cache.Lookup("key2"));
57 EXPECT_EQ(nullptr, cache.Lookup("key3"));
58 EXPECT_EQ(0u, cache.size());
60 EXPECT_EQ(1u, session1->references);
61 EXPECT_EQ(1u, session2->references);
62 EXPECT_EQ(1u, session3->references);
65 // Test that a session may be inserted at two different keys. This should never
66 // be necessary, but the API doesn't prohibit it.
67 TEST(SSLClientSessionCacheOpenSSLTest, DoubleInsert) {
68 SSLClientSessionCacheOpenSSL::Config config;
69 SSLClientSessionCacheOpenSSL cache(config);
71 ScopedSSL_SESSION session(SSL_SESSION_new());
72 EXPECT_EQ(1u, session->references);
74 EXPECT_EQ(nullptr, cache.Lookup("key1"));
75 EXPECT_EQ(nullptr, cache.Lookup("key2"));
76 EXPECT_EQ(0u, cache.size());
78 cache.Insert("key1", session.get());
79 EXPECT_EQ(session.get(), cache.Lookup("key1"));
80 EXPECT_EQ(nullptr, cache.Lookup("key2"));
81 EXPECT_EQ(1u, cache.size());
83 EXPECT_EQ(2u, session->references);
85 cache.Insert("key2", session.get());
86 EXPECT_EQ(session.get(), cache.Lookup("key1"));
87 EXPECT_EQ(session.get(), cache.Lookup("key2"));
88 EXPECT_EQ(2u, cache.size());
90 EXPECT_EQ(3u, session->references);
92 cache.Flush();
93 EXPECT_EQ(nullptr, cache.Lookup("key1"));
94 EXPECT_EQ(nullptr, cache.Lookup("key2"));
95 EXPECT_EQ(0u, cache.size());
97 EXPECT_EQ(1u, session->references);
100 // Tests that the session cache's size is correctly bounded.
101 TEST(SSLClientSessionCacheOpenSSLTest, MaxEntries) {
102 SSLClientSessionCacheOpenSSL::Config config;
103 config.max_entries = 3;
104 SSLClientSessionCacheOpenSSL cache(config);
106 ScopedSSL_SESSION session1(SSL_SESSION_new());
107 ScopedSSL_SESSION session2(SSL_SESSION_new());
108 ScopedSSL_SESSION session3(SSL_SESSION_new());
109 ScopedSSL_SESSION session4(SSL_SESSION_new());
111 // Insert three entries.
112 cache.Insert("key1", session1.get());
113 cache.Insert("key2", session2.get());
114 cache.Insert("key3", session3.get());
115 EXPECT_EQ(session1.get(), cache.Lookup("key1"));
116 EXPECT_EQ(session2.get(), cache.Lookup("key2"));
117 EXPECT_EQ(session3.get(), cache.Lookup("key3"));
118 EXPECT_EQ(3u, cache.size());
120 // On insertion of a fourth, the first is removed.
121 cache.Insert("key4", session4.get());
122 EXPECT_EQ(nullptr, cache.Lookup("key1"));
123 EXPECT_EQ(session4.get(), cache.Lookup("key4"));
124 EXPECT_EQ(session3.get(), cache.Lookup("key3"));
125 EXPECT_EQ(session2.get(), cache.Lookup("key2"));
126 EXPECT_EQ(3u, cache.size());
128 // Despite being newest, the next to be removed is session4 as it was accessed
129 // least. recently.
130 cache.Insert("key1", session1.get());
131 EXPECT_EQ(session1.get(), cache.Lookup("key1"));
132 EXPECT_EQ(session2.get(), cache.Lookup("key2"));
133 EXPECT_EQ(session3.get(), cache.Lookup("key3"));
134 EXPECT_EQ(nullptr, cache.Lookup("key4"));
135 EXPECT_EQ(3u, cache.size());
138 // Tests that session expiration works properly.
139 TEST(SSLClientSessionCacheOpenSSLTest, Expiration) {
140 const size_t kNumEntries = 20;
141 const size_t kExpirationCheckCount = 10;
142 const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(1000);
144 SSLClientSessionCacheOpenSSL::Config config;
145 config.expiration_check_count = kExpirationCheckCount;
146 config.timeout = kTimeout;
147 SSLClientSessionCacheOpenSSL cache(config);
148 base::SimpleTestClock* clock = new base::SimpleTestClock;
149 cache.SetClockForTesting(make_scoped_ptr(clock));
151 // Add |kNumEntries - 1| entries.
152 for (size_t i = 0; i < kNumEntries - 1; i++) {
153 ScopedSSL_SESSION session(SSL_SESSION_new());
154 cache.Insert(base::SizeTToString(i), session.get());
156 EXPECT_EQ(kNumEntries - 1, cache.size());
158 // Expire all the previous entries and insert one more entry.
159 clock->Advance(kTimeout * 2);
160 ScopedSSL_SESSION session(SSL_SESSION_new());
161 cache.Insert("key", session.get());
163 // All entries are still in the cache.
164 EXPECT_EQ(kNumEntries, cache.size());
166 // Perform one fewer lookup than needed to trigger the expiration check. This
167 // shall not expire any session.
168 for (size_t i = 0; i < kExpirationCheckCount - 1; i++)
169 cache.Lookup("key");
171 // All entries are still in the cache.
172 EXPECT_EQ(kNumEntries, cache.size());
174 // Perform one more lookup. This will expire all sessions but the last one.
175 cache.Lookup("key");
176 EXPECT_EQ(1u, cache.size());
177 EXPECT_EQ(session.get(), cache.Lookup("key"));
178 for (size_t i = 0; i < kNumEntries - 1; i++) {
179 SCOPED_TRACE(i);
180 EXPECT_EQ(nullptr, cache.Lookup(base::SizeTToString(i)));
184 // Tests that Lookup performs an expiration check before returning a cached
185 // session.
186 TEST(SSLClientSessionCacheOpenSSLTest, LookupExpirationCheck) {
187 // kExpirationCheckCount is set to a suitably large number so the automated
188 // pruning never triggers.
189 const size_t kExpirationCheckCount = 1000;
190 const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(1000);
192 SSLClientSessionCacheOpenSSL::Config config;
193 config.expiration_check_count = kExpirationCheckCount;
194 config.timeout = kTimeout;
195 SSLClientSessionCacheOpenSSL cache(config);
196 base::SimpleTestClock* clock = new base::SimpleTestClock;
197 cache.SetClockForTesting(make_scoped_ptr(clock));
199 // Insert an entry into the session cache.
200 ScopedSSL_SESSION session(SSL_SESSION_new());
201 cache.Insert("key", session.get());
202 EXPECT_EQ(session.get(), cache.Lookup("key"));
203 EXPECT_EQ(1u, cache.size());
205 // Expire the session.
206 clock->Advance(kTimeout * 2);
208 // The entry has not been removed yet.
209 EXPECT_EQ(1u, cache.size());
211 // But it will not be returned on lookup and gets pruned at that point.
212 EXPECT_EQ(nullptr, cache.Lookup("key"));
213 EXPECT_EQ(0u, cache.size());
215 // Sessions also are treated as expired if the clock rewinds.
216 cache.Insert("key", session.get());
217 EXPECT_EQ(session.get(), cache.Lookup("key"));
218 EXPECT_EQ(1u, cache.size());
220 clock->Advance(-kTimeout * 2);
222 EXPECT_EQ(nullptr, cache.Lookup("key"));
223 EXPECT_EQ(0u, cache.size());
226 } // namespace net