OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014 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/http/disk_based_cert_cache.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/callback_helpers.h" | |
9 #include "net/base/completion_callback.h" | |
10 #include "net/base/net_errors.h" | |
11 #include "net/base/test_completion_callback.h" | |
12 #include "net/base/test_data_directory.h" | |
13 #include "net/disk_cache/memory/mem_backend_impl.h" | |
14 #include "net/http/mock_http_cache.h" | |
15 #include "net/test/cert_test_util.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 namespace net { | |
19 | |
20 namespace { | |
21 | |
22 const char kCertTransaction1Key[] = | |
23 "cert:4C005EF1CF45F80D4A5A2BCFB00D4F198121E8D4"; | |
24 const char kCertTransaction2Key[] = | |
25 "cert:9174C7CB9E4919604E7B1BFC430E4929DA45F65F"; | |
26 | |
27 // MockTransactions are required to use the MockDiskCache backend. | |
28 // This transaction corresponds to "root_ca_cert.pem" in | |
29 // GetTestCertsDirectory(). | |
30 const MockTransaction kCertTransaction1 = { | |
31 kCertTransaction1Key, "", base::Time(), "", LOAD_NORMAL, "", "", | |
32 base::Time(), "", TEST_MODE_NORMAL, NULL, 0, OK}; | |
33 | |
34 // This transaction corresponds to "ok_cert.pem" in GetTestCertsDirectory(). | |
35 const MockTransaction kCertTransaction2 = { | |
36 kCertTransaction2Key, "", base::Time(), "", LOAD_NORMAL, "", "", | |
37 base::Time(), "", TEST_MODE_NORMAL, NULL, 0, OK}; | |
38 | |
39 // MockCertCache is used so that results from the DiskBasedCertCache can be | |
40 // received using TestCompletionCallback::GetResult. | |
41 class MockCertCache { | |
42 public: | |
43 MockCertCache() | |
44 : backend(new MockDiskCache()), | |
45 cert_cache_(new DiskBasedCertCache(backend.get())) {} | |
46 | |
47 int Set(X509Certificate::OSCertHandle cert_handle, | |
48 std::string* key, | |
49 const CompletionCallback& callback) { | |
50 cert_cache_->Set(cert_handle, | |
51 base::Bind(&MockCertCache::OnSetComplete, | |
52 base::Unretained(this), | |
53 key, | |
54 callback)); | |
55 return ERR_IO_PENDING; | |
56 } | |
57 | |
58 int Get(const std::string& key, | |
59 X509Certificate::OSCertHandle* cert_handle, | |
60 const CompletionCallback& callback) { | |
61 cert_cache_->Get(key, | |
62 base::Bind(&MockCertCache::OnGetComplete, | |
63 base::Unretained(this), | |
64 cert_handle, | |
65 callback)); | |
66 return ERR_IO_PENDING; | |
67 } | |
68 | |
69 void OnSetComplete(std::string* key_return, | |
70 CompletionCallback callback, | |
71 const std::string& key_retrieved) { | |
72 *key_return = key_retrieved; | |
73 callback.Run(OK); | |
74 } | |
75 | |
76 void OnGetComplete(X509Certificate::OSCertHandle* handle_return, | |
77 CompletionCallback callback, | |
78 const X509Certificate::OSCertHandle handle_retrieved) { | |
79 *handle_return = handle_retrieved; | |
80 callback.Run(OK); | |
81 } | |
82 | |
83 void DeleteCertCache() { cert_cache_.reset(); } | |
84 | |
85 private: | |
86 scoped_ptr<disk_cache::Backend> backend; | |
87 scoped_ptr<DiskBasedCertCache> cert_cache_; | |
88 }; | |
89 | |
90 } // namespace | |
91 | |
92 // ---------------------------------------------------------------------------- | |
93 | |
94 // Tests that a certificate can be stored in the cache. | |
95 TEST(DiskBasedCertCache, SetCert) { | |
96 AddMockTransaction(&kCertTransaction1); | |
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion/review: You want to use Scop
| |
97 MockCertCache user; | |
98 scoped_refptr<X509Certificate> cert( | |
99 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
100 ASSERT_TRUE(cert.get()); | |
101 | |
102 TestCompletionCallback set_callback; | |
103 std::string key; | |
104 | |
105 int rv = | |
106 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
107 rv = set_callback.GetResult(rv); | |
108 EXPECT_EQ(OK, rv); | |
109 EXPECT_FALSE(key.empty()); | |
Ryan Sleevi
2014/06/24 22:00:59
Notes from discussion/review:
You should also ver
| |
110 } | |
111 | |
112 // Tests that attempting to retrieve a cert that is not in the cache will | |
113 // return NULL. | |
114 TEST(DiskBasedCertCache, GetUncachedCert) { | |
115 AddMockTransaction(&kCertTransaction1); | |
116 MockCertCache user; | |
117 TestCompletionCallback get_callback; | |
118 X509Certificate::OSCertHandle cert_handle = NULL; | |
119 | |
120 int rv = | |
121 user.Get(kCertTransaction1Key, &cert_handle, get_callback.callback()); | |
122 rv = get_callback.GetResult(rv); | |
123 EXPECT_EQ(OK, rv); | |
124 EXPECT_EQ(NULL, cert_handle); | |
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion/review:
BUG: cert_handle ha
| |
125 } | |
126 | |
127 // Issues two requests to store a certificate in the cache | |
128 // (simultaneously), and checks that the DiskBasedCertCache stores the | |
129 // certificate to the cache (in one write rather than two). | |
130 TEST(DiskBasedCertCache, SetMultiple) { | |
131 AddMockTransaction(&kCertTransaction1); | |
132 MockCertCache user; | |
133 | |
134 scoped_refptr<X509Certificate> cert( | |
135 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
136 ASSERT_TRUE(cert.get()); | |
137 | |
138 TestCompletionCallback set_callback1; | |
139 TestCompletionCallback set_callback2; | |
140 | |
141 std::string key1, key2; | |
142 | |
143 int rv1 = | |
144 user.Set(cert.get()->os_cert_handle(), &key1, set_callback1.callback()); | |
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion/review:
No need to use "cer
| |
145 int rv2 = | |
146 user.Set(cert.get()->os_cert_handle(), &key2, set_callback2.callback()); | |
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion/review:
This isn't matching
| |
147 | |
148 rv1 = set_callback1.GetResult(rv1); | |
149 EXPECT_EQ(OK, rv1); | |
150 rv2 = set_callback2.GetResult(rv2); | |
151 EXPECT_EQ(OK, rv2); | |
152 EXPECT_EQ(key1, key2); | |
153 } | |
154 | |
155 // Stores a certificate in the DiskBasedCertCache, then retrieves it | |
156 // and makes sure it was retrieved successfully. | |
157 TEST(DiskBasedCertCache, SimpleSetAndGet) { | |
158 AddMockTransaction(&kCertTransaction1); | |
159 MockCertCache user; | |
160 | |
161 scoped_refptr<X509Certificate> cert( | |
162 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
163 ASSERT_TRUE(cert.get()); | |
164 | |
165 TestCompletionCallback set_callback; | |
166 TestCompletionCallback get_callback; | |
167 std::string key; | |
168 | |
169 X509Certificate::OSCertHandle retrieved_cert_handle = NULL; | |
170 int rv = | |
171 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
172 rv = set_callback.GetResult(rv); | |
173 EXPECT_EQ(OK, rv); | |
174 rv = user.Get(key, &retrieved_cert_handle, get_callback.callback()); | |
175 rv = get_callback.GetResult(rv); | |
176 EXPECT_EQ(OK, rv); | |
177 EXPECT_TRUE(X509Certificate::IsSameOSCert(retrieved_cert_handle, | |
178 cert.get()->os_cert_handle())); | |
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion/review:
BUG: As noted, |ret
| |
179 } | |
180 | |
Ryan Sleevi
2014/06/24 22:00:59
TEST: You want to have a test where a Get() from a
Ryan Sleevi
2014/06/24 22:01:00
TEST: You want to have a test where a Get() from a
| |
181 // Tests some basic functionality of the DiskBasedCertCache, with multiple | |
182 // set and get operations. | |
183 TEST(DiskBasedCertCache, BasicUsage) { | |
184 AddMockTransaction(&kCertTransaction1); | |
185 AddMockTransaction(&kCertTransaction2); | |
186 MockCertCache user; | |
187 | |
188 scoped_refptr<X509Certificate> cert1( | |
189 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
190 scoped_refptr<X509Certificate> cert2( | |
191 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); | |
192 ASSERT_TRUE(cert1.get()); | |
193 ASSERT_TRUE(cert2.get()); | |
194 ASSERT_FALSE(X509Certificate::IsSameOSCert(cert1->os_cert_handle(), | |
195 cert2->os_cert_handle())); | |
196 TestCompletionCallback set_callback1, set_callback2; | |
197 std::string key1, key2; | |
198 | |
199 int rv1 = | |
200 user.Set(cert1.get()->os_cert_handle(), &key1, set_callback1.callback()); | |
201 int rv2 = | |
202 user.Set(cert2.get()->os_cert_handle(), &key2, set_callback2.callback()); | |
203 | |
204 rv1 = set_callback1.GetResult(rv1); | |
205 EXPECT_EQ(OK, rv1); | |
206 rv2 = set_callback2.GetResult(rv2); | |
207 EXPECT_EQ(OK, rv2); | |
208 | |
209 TestCompletionCallback get_callback1, get_callback2; | |
210 X509Certificate::OSCertHandle cert_handle1, cert_handle2; | |
211 | |
212 rv1 = user.Get(key1, &cert_handle1, get_callback1.callback()); | |
213 rv2 = user.Get(key2, &cert_handle2, get_callback2.callback()); | |
214 | |
215 rv1 = get_callback1.GetResult(rv1); | |
216 EXPECT_EQ(OK, rv1); | |
217 rv2 = get_callback2.GetResult(rv2); | |
218 EXPECT_EQ(OK, rv2); | |
219 | |
220 EXPECT_TRUE( | |
221 X509Certificate::IsSameOSCert(cert1->os_cert_handle(), cert_handle1)); | |
222 EXPECT_TRUE( | |
223 X509Certificate::IsSameOSCert(cert2->os_cert_handle(), cert_handle2)); | |
224 } | |
225 | |
226 // Test the result of simultaneous requests to store and retrieve a | |
227 // certificate from the cache. Since it is unknown whether the set or get | |
228 // operation will complete first, this test is just to make sure that it | |
229 // does not crash. | |
Ryan Sleevi
2014/06/24 22:01:00
Notes from discussion:
You'll want your test harn
| |
230 TEST(DiskBasedCertCache, SimultaneousSetGet) { | |
231 AddMockTransaction(&kCertTransaction1); | |
232 MockCertCache user; | |
233 TestCompletionCallback set_callback, get_callback; | |
234 X509Certificate::OSCertHandle cert_handle; | |
235 std::string key("cert:4C005EF1CF45F80D4A5A2BCFB00D4F198121E8D4"); | |
Ryan Sleevi
2014/06/24 22:00:59
Reuse transaction key?
| |
236 | |
237 scoped_refptr<X509Certificate> cert( | |
238 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
239 ASSERT_TRUE(cert.get()); | |
240 | |
241 int rv1 = | |
242 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
243 int rv2 = user.Get(key, &cert_handle, get_callback.callback()); | |
244 rv1 = get_callback.GetResult(rv1); | |
245 EXPECT_EQ(OK, rv1); | |
246 rv2 = set_callback.GetResult(rv2); | |
247 EXPECT_EQ(OK, rv2); | |
248 } | |
249 | |
Ryan Sleevi
2014/06/24 22:01:00
TEST: Use the MockTransactions to alter the sync/a
| |
250 // Tests that the DiskBasedCertCache can be deleted without issues when | |
251 // there are pending operations in the disk cache. | |
252 TEST(DiskBasedCertCache, DeletedCertCache) { | |
253 AddMockTransaction(&kCertTransaction1); | |
254 MockCertCache user; | |
255 std::string key; | |
256 scoped_refptr<X509Certificate> cert( | |
257 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
258 ASSERT_TRUE(cert.get()); | |
259 | |
260 TestCompletionCallback set_callback; | |
261 int rv = | |
262 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
263 | |
264 user.DeleteCertCache(); | |
265 rv = set_callback.GetResult(rv); | |
266 EXPECT_EQ(OK, rv); | |
267 EXPECT_EQ(std::string(), key); | |
268 } | |
269 | |
270 } // namespace net | |
OLD | NEW |