OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "net/ssl/ssl_client_session_cache_openssl.h" | |
6 | |
7 #include <openssl/ssl.h> | |
8 | |
9 #include "base/strings/string_number_conversions.h" | |
10 #include "net/ssl/scoped_openssl_types.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 | |
13 namespace net { | |
14 | |
15 namespace { | |
16 | |
17 class TestSSLClientSessionCacheOpenSSL : public SSLClientSessionCacheOpenSSL { | |
18 public: | |
19 explicit TestSSLClientSessionCacheOpenSSL(const Config& config) | |
20 : SSLClientSessionCacheOpenSSL(config) {} | |
21 | |
22 void AdvanceClock(base::TimeDelta delta) { now_ += delta; } | |
23 | |
24 protected: | |
25 base::Time Now() override { return now_; } | |
26 | |
27 private: | |
28 base::Time now_; | |
29 }; | |
30 | |
31 } // namespace | |
32 | |
33 // Test basic insertion and lookup operations. | |
34 TEST(SSLClientSessionCacheOpenSSLTest, Basic) { | |
35 SSLClientSessionCacheOpenSSL::Config config; | |
36 TestSSLClientSessionCacheOpenSSL cache(config); | |
37 | |
38 ScopedSSL_SESSION session1(SSL_SESSION_new()); | |
39 ScopedSSL_SESSION session2(SSL_SESSION_new()); | |
40 ScopedSSL_SESSION session3(SSL_SESSION_new()); | |
41 EXPECT_EQ(1, session1->references); | |
42 EXPECT_EQ(1, session2->references); | |
43 EXPECT_EQ(1, session3->references); | |
44 | |
45 EXPECT_EQ(nullptr, cache.Lookup("key1")); | |
46 EXPECT_EQ(nullptr, cache.Lookup("key2")); | |
47 EXPECT_EQ(0u, cache.size()); | |
48 | |
49 cache.Insert("key1", session1.get()); | |
50 EXPECT_EQ(session1.get(), cache.Lookup("key1")); | |
51 EXPECT_EQ(nullptr, cache.Lookup("key2")); | |
52 EXPECT_EQ(1u, cache.size()); | |
53 | |
54 cache.Insert("key2", session2.get()); | |
55 EXPECT_EQ(session1.get(), cache.Lookup("key1")); | |
56 EXPECT_EQ(session2.get(), cache.Lookup("key2")); | |
57 EXPECT_EQ(2u, cache.size()); | |
58 | |
59 EXPECT_EQ(2, session1->references); | |
60 EXPECT_EQ(2, session2->references); | |
61 | |
62 cache.Insert("key1", session3.get()); | |
63 EXPECT_EQ(session3.get(), cache.Lookup("key1")); | |
64 EXPECT_EQ(session2.get(), cache.Lookup("key2")); | |
65 EXPECT_EQ(2u, cache.size()); | |
66 | |
67 EXPECT_EQ(1, session1->references); | |
68 EXPECT_EQ(2, session2->references); | |
69 EXPECT_EQ(2, session3->references); | |
70 | |
71 cache.Flush(); | |
72 EXPECT_EQ(nullptr, cache.Lookup("key1")); | |
73 EXPECT_EQ(nullptr, cache.Lookup("key2")); | |
74 EXPECT_EQ(nullptr, cache.Lookup("key3")); | |
75 EXPECT_EQ(0u, cache.size()); | |
76 | |
77 EXPECT_EQ(1, session1->references); | |
78 EXPECT_EQ(1, session2->references); | |
79 EXPECT_EQ(1, session3->references); | |
80 } | |
81 | |
82 // Test that a session may be inserted at two different keys. This should never | |
83 // be necessary, but the API doesn't prohibit it. | |
84 TEST(SSLClientSessionCacheOpenSSLTest, DoubleInsert) { | |
85 SSLClientSessionCacheOpenSSL::Config config; | |
86 TestSSLClientSessionCacheOpenSSL cache(config); | |
87 | |
88 ScopedSSL_SESSION session(SSL_SESSION_new()); | |
89 EXPECT_EQ(1, session->references); | |
90 | |
91 EXPECT_EQ(nullptr, cache.Lookup("key1")); | |
92 EXPECT_EQ(nullptr, cache.Lookup("key2")); | |
93 EXPECT_EQ(0u, cache.size()); | |
94 | |
95 cache.Insert("key1", session.get()); | |
96 EXPECT_EQ(session.get(), cache.Lookup("key1")); | |
97 EXPECT_EQ(nullptr, cache.Lookup("key2")); | |
98 EXPECT_EQ(1u, cache.size()); | |
99 | |
100 EXPECT_EQ(2, session->references); | |
101 | |
102 cache.Insert("key2", session.get()); | |
103 EXPECT_EQ(session.get(), cache.Lookup("key1")); | |
104 EXPECT_EQ(session.get(), cache.Lookup("key2")); | |
105 EXPECT_EQ(2u, cache.size()); | |
106 | |
107 EXPECT_EQ(3, session->references); | |
108 | |
109 cache.Flush(); | |
110 EXPECT_EQ(nullptr, cache.Lookup("key1")); | |
111 EXPECT_EQ(nullptr, cache.Lookup("key2")); | |
112 EXPECT_EQ(0u, cache.size()); | |
113 | |
114 EXPECT_EQ(1, session->references); | |
115 } | |
116 | |
117 // Tests that the session cache's size is correctly bounded. | |
118 TEST(SSLClientSessionCacheOpenSSLTest, MaxEntries) { | |
119 SSLClientSessionCacheOpenSSL::Config config; | |
120 config.max_entries = 3; | |
121 TestSSLClientSessionCacheOpenSSL cache(config); | |
122 | |
123 ScopedSSL_SESSION session1(SSL_SESSION_new()); | |
124 ScopedSSL_SESSION session2(SSL_SESSION_new()); | |
125 ScopedSSL_SESSION session3(SSL_SESSION_new()); | |
126 ScopedSSL_SESSION session4(SSL_SESSION_new()); | |
127 | |
128 // Insert three entries. | |
129 cache.Insert("key1", session1.get()); | |
130 cache.Insert("key2", session2.get()); | |
131 cache.Insert("key3", session3.get()); | |
132 EXPECT_EQ(session1.get(), cache.Lookup("key1")); | |
133 EXPECT_EQ(session2.get(), cache.Lookup("key2")); | |
134 EXPECT_EQ(session3.get(), cache.Lookup("key3")); | |
135 EXPECT_EQ(3u, cache.size()); | |
136 | |
137 // On insertion of a fourth, the first is removed. | |
138 cache.Insert("key4", session4.get()); | |
139 EXPECT_EQ(nullptr, cache.Lookup("key1")); | |
140 EXPECT_EQ(session4.get(), cache.Lookup("key4")); | |
141 EXPECT_EQ(session3.get(), cache.Lookup("key3")); | |
142 EXPECT_EQ(session2.get(), cache.Lookup("key2")); | |
143 EXPECT_EQ(3u, cache.size()); | |
144 | |
145 // Despite being newest, the next to be removed is session4 as it was accessed | |
146 // least. recently. | |
147 cache.Insert("key1", session1.get()); | |
148 EXPECT_EQ(session1.get(), cache.Lookup("key1")); | |
149 EXPECT_EQ(session2.get(), cache.Lookup("key2")); | |
150 EXPECT_EQ(session3.get(), cache.Lookup("key3")); | |
151 EXPECT_EQ(nullptr, cache.Lookup("key4")); | |
152 EXPECT_EQ(3u, cache.size()); | |
153 } | |
154 | |
155 // Tests that session expiration works properly. | |
156 TEST(SSLClientSessionCacheOpenSSLTest, Expiration) { | |
157 const size_t kNumEntries = 20; | |
158 | |
159 SSLClientSessionCacheOpenSSL::Config config; | |
160 config.expiration_check_count = 10; | |
161 config.timeout = base::TimeDelta::FromSeconds(1000); | |
162 TestSSLClientSessionCacheOpenSSL cache(config); | |
163 | |
164 // Add |kNumEntries - 1| entries. | |
165 for (size_t i = 0; i < kNumEntries - 1; i++) { | |
166 ScopedSSL_SESSION session(SSL_SESSION_new()); | |
167 cache.Insert(base::SizeTToString(i), session.get()); | |
168 cache.AdvanceClock(base::TimeDelta::FromSeconds(1)); | |
169 } | |
170 EXPECT_EQ(kNumEntries - 1, cache.size()); | |
171 | |
172 // Expire all the previous entries and insert one more entry. | |
173 cache.AdvanceClock(base::TimeDelta::FromSeconds(2000)); | |
174 ScopedSSL_SESSION session(SSL_SESSION_new()); | |
175 cache.Insert("key", session.get()); | |
176 | |
177 // All entries are still in the cache. | |
178 EXPECT_EQ(kNumEntries, cache.size()); | |
179 | |
180 // Perform |config.expiration_check_count - 1| lookups. This shall not expire | |
181 // any session. | |
182 for (size_t i = 0; i < config.expiration_check_count - 1; i++) { | |
Ryan Sleevi
2015/03/17 00:50:34
superflous braces
davidben
2015/03/20 22:41:27
Even on a for loop? Eugh, okay...
| |
183 cache.Lookup("key"); | |
184 } | |
185 | |
186 // All entries are still in the cache. | |
187 EXPECT_EQ(kNumEntries, cache.size()); | |
188 | |
189 // Perform one more lookup. This will expire all sessions but the last one. | |
190 cache.Lookup("key"); | |
191 EXPECT_EQ(1u, cache.size()); | |
192 EXPECT_EQ(session.get(), cache.Lookup("key")); | |
193 for (size_t i = 0; i < kNumEntries - 1; i++) { | |
194 SCOPED_TRACE(i); | |
195 EXPECT_EQ(nullptr, cache.Lookup(base::SizeTToString(i))); | |
196 } | |
197 } | |
198 | |
199 } // namespace net | |
OLD | NEW |