Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: components/certificate_transparency/log_proof_fetcher_unittest.cc

Issue 1405293009: Certificate Transparency: Fetching consistency proofs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Catching up with master Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/certificate_transparency/log_proof_fetcher.cc ('k') | net/base/net_error_list.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/certificate_transparency/log_proof_fetcher.h" 5 #include "components/certificate_transparency/log_proof_fetcher.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/format_macros.h"
10 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/run_loop.h"
11 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
12 #include "components/safe_json/testing_json_parser.h" 14 #include "components/safe_json/testing_json_parser.h"
13 #include "net/base/net_errors.h" 15 #include "net/base/net_errors.h"
14 #include "net/base/network_delegate.h" 16 #include "net/base/network_delegate.h"
15 #include "net/cert/signed_tree_head.h" 17 #include "net/cert/signed_tree_head.h"
16 #include "net/http/http_status_code.h" 18 #include "net/http/http_status_code.h"
17 #include "net/test/ct_test_util.h" 19 #include "net/test/ct_test_util.h"
18 #include "net/url_request/url_request_context.h" 20 #include "net/url_request/url_request_context.h"
19 #include "net/url_request/url_request_filter.h" 21 #include "net/url_request/url_request_filter.h"
20 #include "net/url_request/url_request_interceptor.h" 22 #include "net/url_request/url_request_interceptor.h"
21 #include "net/url_request/url_request_job.h" 23 #include "net/url_request/url_request_job.h"
22 #include "net/url_request/url_request_test_job.h" 24 #include "net/url_request/url_request_test_job.h"
23 #include "net/url_request/url_request_test_util.h" 25 #include "net/url_request/url_request_test_util.h"
24 #include "testing/gtest/include/gtest/gtest.h" 26 #include "testing/gtest/include/gtest/gtest.h"
25 27
26 namespace certificate_transparency { 28 namespace certificate_transparency {
27 29
28 namespace { 30 namespace {
29 31
30 const char kGetSTHHeaders[] = 32 const char kGetResponseHeaders[] =
31 "HTTP/1.1 200 OK\n" 33 "HTTP/1.1 200 OK\n"
32 "Content-Type: application/json; charset=ISO-8859-1\n"; 34 "Content-Type: application/json; charset=ISO-8859-1\n";
33 35
34 const char kGetSTHNotFoundHeaders[] = 36 const char kGetResponseNotFoundHeaders[] =
35 "HTTP/1.1 404 Not Found\n" 37 "HTTP/1.1 404 Not Found\n"
36 "Content-Type: text/html; charset=iso-8859-1\n"; 38 "Content-Type: text/html; charset=iso-8859-1\n";
37 39
38 const char kLogSchema[] = "https"; 40 const char kLogSchema[] = "https";
39 const char kLogHost[] = "ct.log.example.com"; 41 const char kLogHost[] = "ct.log.example.com";
40 const char kLogPathPrefix[] = "somelog"; 42 const char kLogPathPrefix[] = "somelog";
41 const char kLogID[] = "some_id"; 43 const char kLogID[] = "some_id";
42 44
43 class FetchSTHTestJob : public net::URLRequestTestJob { 45 // Gets a dummy consistency proof for the given |node_id|.
46 std::string GetDummyConsistencyProofNode(uint64_t node_id) {
47 // Take the low 8 bits and repeat them as a string. This
48 // has no special meaning, other than making it easier to
49 // debug which consistency proof was used.
50 return std::string(32, static_cast<char>(node_id));
51 }
52
53 // Number of nodes in a dummy consistency proof.
54 const size_t kDummyConsistencyProofNumNodes = 4;
55
56 class LogFetchTestJob : public net::URLRequestTestJob {
44 public: 57 public:
45 FetchSTHTestJob(const std::string& get_sth_data, 58 LogFetchTestJob(const std::string& get_log_data,
46 const std::string& get_sth_headers, 59 const std::string& get_log_headers,
47 net::URLRequest* request, 60 net::URLRequest* request,
48 net::NetworkDelegate* network_delegate) 61 net::NetworkDelegate* network_delegate)
49 : URLRequestTestJob(request, 62 : URLRequestTestJob(request,
50 network_delegate, 63 network_delegate,
51 get_sth_headers, 64 get_log_headers,
52 get_sth_data, 65 get_log_data,
53 true), 66 true),
54 async_io_(false) {} 67 async_io_(false) {}
55 68
56 void set_async_io(bool async_io) { async_io_ = async_io; } 69 void set_async_io(bool async_io) { async_io_ = async_io; }
57 70
58 private: 71 private:
59 ~FetchSTHTestJob() override {} 72 ~LogFetchTestJob() override {}
60 73
61 bool NextReadAsync() override { 74 bool NextReadAsync() override {
62 // Response with indication of async IO only once, otherwise the final 75 // Response with indication of async IO only once, otherwise the final
63 // Read would (incorrectly) be classified as async, causing the 76 // Read would (incorrectly) be classified as async, causing the
64 // URLRequestJob to try reading another time and failing on a CHECK 77 // URLRequestJob to try reading another time and failing on a CHECK
65 // that the raw_read_buffer_ is not null. 78 // that the raw_read_buffer_ is not null.
66 // According to mmenke@, this is a bug in the URLRequestTestJob code. 79 // According to mmenke@, this is a bug in the URLRequestTestJob code.
67 // TODO(eranm): Once said bug is fixed, switch most tests to using async 80 // TODO(eranm): Once said bug is fixed, switch most tests to using async
68 // IO. 81 // IO.
69 if (async_io_) { 82 if (async_io_) {
70 async_io_ = false; 83 async_io_ = false;
71 return true; 84 return true;
72 } 85 }
73 return false; 86 return false;
74 } 87 }
75 88
76 bool async_io_; 89 bool async_io_;
77 90
78 DISALLOW_COPY_AND_ASSIGN(FetchSTHTestJob); 91 DISALLOW_COPY_AND_ASSIGN(LogFetchTestJob);
79 }; 92 };
80 93
81 class GetSTHResponseHandler : public net::URLRequestInterceptor { 94 class LogGetResponseHandler : public net::URLRequestInterceptor {
82 public: 95 public:
83 GetSTHResponseHandler() 96 LogGetResponseHandler()
84 : async_io_(false), 97 : async_io_(false),
85 response_body_(""),
86 response_headers_( 98 response_headers_(
87 std::string(kGetSTHHeaders, arraysize(kGetSTHHeaders))) {} 99 std::string(kGetResponseHeaders, arraysize(kGetResponseHeaders))) {}
88 ~GetSTHResponseHandler() override {} 100 ~LogGetResponseHandler() override {}
89 101
90 // URLRequestInterceptor implementation: 102 // URLRequestInterceptor implementation:
91 net::URLRequestJob* MaybeInterceptRequest( 103 net::URLRequestJob* MaybeInterceptRequest(
92 net::URLRequest* request, 104 net::URLRequest* request,
93 net::NetworkDelegate* network_delegate) const override { 105 net::NetworkDelegate* network_delegate) const override {
94 std::string expected_url = base::StringPrintf( 106 EXPECT_EQ(expected_url_, request->url());
95 "%s://%s/%s/ct/v1/get-sth", kLogSchema, kLogHost, kLogPathPrefix); 107
96 EXPECT_EQ(GURL(expected_url), request->url()); 108 LogFetchTestJob* job = new LogFetchTestJob(
97 FetchSTHTestJob* job = new FetchSTHTestJob(
98 response_body_, response_headers_, request, network_delegate); 109 response_body_, response_headers_, request, network_delegate);
99 job->set_async_io(async_io_); 110 job->set_async_io(async_io_);
100 return job; 111 return job;
101 } 112 }
102 113
103 void set_response_body(const std::string& response_body) { 114 void set_response_body(const std::string& response_body) {
104 response_body_ = response_body; 115 response_body_ = response_body;
105 } 116 }
106 117
107 void set_response_headers(const std::string& response_headers) { 118 void set_response_headers(const std::string& response_headers) {
108 response_headers_ = response_headers; 119 response_headers_ = response_headers;
109 } 120 }
110 121
111 void set_async_io(bool async_io) { async_io_ = async_io; } 122 void set_async_io(bool async_io) { async_io_ = async_io; }
112 123
124 void set_expected_url(const GURL& url) { expected_url_ = url; }
125
113 private: 126 private:
114 bool async_io_; 127 bool async_io_;
115 std::string response_body_; 128 std::string response_body_;
116 std::string response_headers_; 129 std::string response_headers_;
117 130
118 DISALLOW_COPY_AND_ASSIGN(GetSTHResponseHandler); 131 // Stored for test body to assert on
132 GURL expected_url_;
133
134 DISALLOW_COPY_AND_ASSIGN(LogGetResponseHandler);
135 };
136
137 enum InterceptedResultType {
138 NOTHING,
139 FAILURE,
140 STH_FETCH,
141 CONSISTENCY_PROOF_FETCH
119 }; 142 };
120 143
121 class RecordFetchCallbackInvocations { 144 class RecordFetchCallbackInvocations {
122 public: 145 public:
123 RecordFetchCallbackInvocations(bool expect_success) 146 RecordFetchCallbackInvocations(bool expect_success)
124 : expect_success_(expect_success), 147 : expect_success_(expect_success),
125 invoked_(false),
126 net_error_(net::OK), 148 net_error_(net::OK),
127 http_response_code_(-1) {} 149 http_response_code_(-1),
150 request_type_(NOTHING) {}
128 151
129 void STHFetched(const std::string& log_id, 152 void STHFetched(base::Closure quit_closure,
153 const std::string& log_id,
130 const net::ct::SignedTreeHead& sth) { 154 const net::ct::SignedTreeHead& sth) {
131 ASSERT_TRUE(expect_success_); 155 ASSERT_TRUE(expect_success_);
132 ASSERT_FALSE(invoked_); 156 ASSERT_EQ(NOTHING, request_type_);
133 invoked_ = true; 157 request_type_ = STH_FETCH;
134 // If expected to succeed, expecting the known_good STH. 158 sth_ = sth;
135 net::ct::SignedTreeHead expected_sth; 159 log_id_ = log_id;
136 net::ct::GetSampleSignedTreeHead(&expected_sth); 160 quit_closure.Run();
137
138 EXPECT_EQ(kLogID, log_id);
139 EXPECT_EQ(expected_sth.version, sth.version);
140 EXPECT_EQ(expected_sth.timestamp, sth.timestamp);
141 EXPECT_EQ(expected_sth.tree_size, sth.tree_size);
142 EXPECT_STREQ(expected_sth.sha256_root_hash, sth.sha256_root_hash);
143 EXPECT_EQ(expected_sth.signature.hash_algorithm,
144 sth.signature.hash_algorithm);
145 EXPECT_EQ(expected_sth.signature.signature_algorithm,
146 sth.signature.signature_algorithm);
147 EXPECT_EQ(expected_sth.signature.signature_data,
148 sth.signature.signature_data);
149 } 161 }
150 162
151 void FetchingFailed(const std::string& log_id, 163 void ConsistencyProofFetched(
164 base::Closure quit_closure,
165 const std::string& log_id,
166 const std::vector<std::string>& consistency_proof) {
167 ASSERT_TRUE(expect_success_);
168 ASSERT_EQ(NOTHING, request_type_);
169 request_type_ = CONSISTENCY_PROOF_FETCH;
170 consistency_proof_.assign(consistency_proof.begin(),
171 consistency_proof.end());
172 log_id_ = log_id;
173 quit_closure.Run();
174 }
175
176 void FetchingFailed(base::Closure quit_closure,
177 const std::string& log_id,
152 int net_error, 178 int net_error,
153 int http_response_code) { 179 int http_response_code) {
154 ASSERT_FALSE(expect_success_); 180 ASSERT_FALSE(expect_success_);
155 ASSERT_FALSE(invoked_); 181 ASSERT_EQ(NOTHING, request_type_);
156 invoked_ = true; 182 request_type_ = FAILURE;
157 net_error_ = net_error; 183 net_error_ = net_error;
158 http_response_code_ = http_response_code; 184 http_response_code_ = http_response_code;
159 if (net_error_ == net::OK) { 185 if (net_error_ == net::OK) {
160 EXPECT_NE(net::HTTP_OK, http_response_code_); 186 EXPECT_NE(net::HTTP_OK, http_response_code_);
161 } 187 }
188
189 quit_closure.Run();
162 } 190 }
163 191
164 bool invoked() const { return invoked_; } 192 InterceptedResultType intercepted_result_type() const {
193 return request_type_;
194 }
165 195
166 int net_error() const { return net_error_; } 196 int net_error() const { return net_error_; }
167 197
168 int http_response_code() const { return http_response_code_; } 198 int http_response_code() const { return http_response_code_; }
169 199
200 const net::ct::SignedTreeHead& intercepted_sth() const { return sth_; }
201
202 const std::string& intercepted_log_id() const { return log_id_; }
203
204 const std::vector<std::string>& intercepted_proof() const {
205 return consistency_proof_;
206 }
207
170 private: 208 private:
171 const bool expect_success_; 209 const bool expect_success_;
172 bool invoked_;
173 int net_error_; 210 int net_error_;
174 int http_response_code_; 211 int http_response_code_;
212 InterceptedResultType request_type_;
213 net::ct::SignedTreeHead sth_;
214 std::string log_id_;
215 std::vector<std::string> consistency_proof_;
175 }; 216 };
176 217
177 class LogProofFetcherTest : public ::testing::Test { 218 class LogProofFetcherTest : public ::testing::Test {
178 public: 219 public:
179 LogProofFetcherTest() 220 LogProofFetcherTest()
180 : log_url_(base::StringPrintf("%s://%s/%s/", 221 : log_url_(base::StringPrintf("%s://%s/%s/",
181 kLogSchema, 222 kLogSchema,
182 kLogHost, 223 kLogHost,
183 kLogPathPrefix)) { 224 kLogPathPrefix)) {
184 scoped_ptr<GetSTHResponseHandler> handler(new GetSTHResponseHandler()); 225 scoped_ptr<LogGetResponseHandler> handler(new LogGetResponseHandler());
185 handler_ = handler.get(); 226 handler_ = handler.get();
186 227
187 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( 228 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
188 kLogSchema, kLogHost, std::move(handler)); 229 kLogSchema, kLogHost, std::move(handler));
189 230
190 fetcher_.reset(new LogProofFetcher(&context_)); 231 fetcher_.reset(new LogProofFetcher(&context_));
191 } 232 }
192 233
193 ~LogProofFetcherTest() override { 234 ~LogProofFetcherTest() override {
194 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(kLogSchema, 235 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(kLogSchema,
195 kLogHost); 236 kLogHost);
196 } 237 }
197 238
198 protected: 239 protected:
199 void SetValidSTHJSONResponse() { 240 void SetValidSTHJSONResponse() {
200 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson(); 241 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson();
201 handler_->set_response_body(sth_json_reply_data); 242 handler_->set_response_body(sth_json_reply_data);
243 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
202 } 244 }
203 245
204 void RunFetcherWithCallback(RecordFetchCallbackInvocations* callback) { 246 void RunFetcherWithCallback(RecordFetchCallbackInvocations* callback) {
205 fetcher_->FetchSignedTreeHead( 247 fetcher_->FetchSignedTreeHead(
206 log_url_, kLogID, 248 log_url_, kLogID,
207 base::Bind(&RecordFetchCallbackInvocations::STHFetched, 249 base::Bind(&RecordFetchCallbackInvocations::STHFetched,
208 base::Unretained(callback)), 250 base::Unretained(callback), run_loop_.QuitClosure()),
209 base::Bind(&RecordFetchCallbackInvocations::FetchingFailed, 251 base::Bind(&RecordFetchCallbackInvocations::FetchingFailed,
210 base::Unretained(callback))); 252 base::Unretained(callback), run_loop_.QuitClosure()));
211 message_loop_.RunUntilIdle(); 253 run_loop_.Run();
212 } 254 }
213 255
256 void RunGetConsistencyFetcherWithCallback(
257 RecordFetchCallbackInvocations* callback) {
258 const uint64_t kOldTree = 5;
259 const uint64_t kNewTree = 8;
260 handler_->set_expected_url(log_url_.Resolve(base::StringPrintf(
261 "ct/v1/get-sth-consistency?first=%" PRIu64 "&second=%" PRIu64, kOldTree,
262 kNewTree)));
263 fetcher_->FetchConsistencyProof(
264 log_url_, kLogID, kOldTree, kNewTree,
265 base::Bind(&RecordFetchCallbackInvocations::ConsistencyProofFetched,
266 base::Unretained(callback), run_loop_.QuitClosure()),
267 base::Bind(&RecordFetchCallbackInvocations::FetchingFailed,
268 base::Unretained(callback), run_loop_.QuitClosure()));
269 run_loop_.Run();
270 }
271
272 void VerifyReceivedSTH(const std::string& log_id,
273 const net::ct::SignedTreeHead& sth) {
274 net::ct::SignedTreeHead expected_sth;
275 net::ct::GetSampleSignedTreeHead(&expected_sth);
276
277 EXPECT_EQ(kLogID, log_id);
278 EXPECT_EQ(expected_sth.version, sth.version);
279 EXPECT_EQ(expected_sth.timestamp, sth.timestamp);
280 EXPECT_EQ(expected_sth.tree_size, sth.tree_size);
281 EXPECT_STREQ(expected_sth.sha256_root_hash, sth.sha256_root_hash);
282 EXPECT_EQ(expected_sth.signature.hash_algorithm,
283 sth.signature.hash_algorithm);
284 EXPECT_EQ(expected_sth.signature.signature_algorithm,
285 sth.signature.signature_algorithm);
286 EXPECT_EQ(expected_sth.signature.signature_data,
287 sth.signature.signature_data);
288 }
289
290 void VerifyConsistencyProof(
291 const std::string& log_id,
292 const std::vector<std::string>& consistency_proof) {
293 EXPECT_EQ(kLogID, log_id);
294 EXPECT_EQ(kDummyConsistencyProofNumNodes, consistency_proof.size());
295 for (uint64_t i = 0; i < kDummyConsistencyProofNumNodes; ++i) {
296 EXPECT_EQ(GetDummyConsistencyProofNode(i), consistency_proof[i])
297 << " node: " << i;
298 }
299 }
300
301 // The |message_loop_|, while seemingly unused, is necessary
302 // for URL request interception. That is the message loop that
303 // will be used by the RunLoop.
214 base::MessageLoopForIO message_loop_; 304 base::MessageLoopForIO message_loop_;
305 base::RunLoop run_loop_;
215 net::TestURLRequestContext context_; 306 net::TestURLRequestContext context_;
216 safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_; 307 safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_;
217 scoped_ptr<LogProofFetcher> fetcher_; 308 scoped_ptr<LogProofFetcher> fetcher_;
218 const GURL log_url_; 309 const GURL log_url_;
219 GetSTHResponseHandler* handler_; 310 LogGetResponseHandler* handler_;
220 }; 311 };
221 312
222 TEST_F(LogProofFetcherTest, TestValidGetReply) { 313 TEST_F(LogProofFetcherTest, TestValidGetReply) {
223 SetValidSTHJSONResponse(); 314 SetValidSTHJSONResponse();
224 315
225 RecordFetchCallbackInvocations callback(true); 316 RecordFetchCallbackInvocations callback(true);
226 317
227 RunFetcherWithCallback(&callback); 318 RunFetcherWithCallback(&callback);
228 319
229 ASSERT_TRUE(callback.invoked()); 320 ASSERT_EQ(STH_FETCH, callback.intercepted_result_type());
321 VerifyReceivedSTH(callback.intercepted_log_id(), callback.intercepted_sth());
230 } 322 }
231 323
232 TEST_F(LogProofFetcherTest, TestValidGetReplyAsyncIO) { 324 TEST_F(LogProofFetcherTest, TestValidGetReplyAsyncIO) {
233 SetValidSTHJSONResponse(); 325 SetValidSTHJSONResponse();
234 handler_->set_async_io(true); 326 handler_->set_async_io(true);
235 327
236 RecordFetchCallbackInvocations callback(true); 328 RecordFetchCallbackInvocations callback(true);
237 RunFetcherWithCallback(&callback); 329 RunFetcherWithCallback(&callback);
238 330
239 ASSERT_TRUE(callback.invoked()); 331 ASSERT_EQ(STH_FETCH, callback.intercepted_result_type());
332 VerifyReceivedSTH(callback.intercepted_log_id(), callback.intercepted_sth());
240 } 333 }
241 334
242 TEST_F(LogProofFetcherTest, TestInvalidGetReplyIncompleteJSON) { 335 TEST_F(LogProofFetcherTest, TestInvalidGetReplyIncompleteJSON) {
243 std::string sth_json_reply_data = net::ct::CreateSignedTreeHeadJsonString( 336 std::string sth_json_reply_data = net::ct::CreateSignedTreeHeadJsonString(
244 21 /* tree_size */, 123456u /* timestamp */, std::string(), 337 21 /* tree_size */, 123456u /* timestamp */, std::string(),
245 std::string()); 338 std::string());
246 handler_->set_response_body(sth_json_reply_data); 339 handler_->set_response_body(sth_json_reply_data);
340 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
247 341
248 RecordFetchCallbackInvocations callback(false); 342 RecordFetchCallbackInvocations callback(false);
249 RunFetcherWithCallback(&callback); 343 RunFetcherWithCallback(&callback);
250 344
251 ASSERT_TRUE(callback.invoked()); 345 ASSERT_EQ(FAILURE, callback.intercepted_result_type());
252 EXPECT_EQ(net::ERR_CT_STH_INCOMPLETE, callback.net_error()); 346 EXPECT_EQ(net::ERR_CT_STH_INCOMPLETE, callback.net_error());
347 EXPECT_EQ(net::HTTP_OK, callback.http_response_code());
253 } 348 }
254 349
255 TEST_F(LogProofFetcherTest, TestInvalidGetReplyInvalidJSON) { 350 TEST_F(LogProofFetcherTest, TestInvalidGetReplyInvalidJSON) {
256 std::string sth_json_reply_data = "{\"tree_size\":21,\"timestamp\":}"; 351 std::string sth_json_reply_data = "{\"tree_size\":21,\"timestamp\":}";
257 handler_->set_response_body(sth_json_reply_data); 352 handler_->set_response_body(sth_json_reply_data);
353 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
258 354
259 RecordFetchCallbackInvocations callback(false); 355 RecordFetchCallbackInvocations callback(false);
260 RunFetcherWithCallback(&callback); 356 RunFetcherWithCallback(&callback);
261 357
262 ASSERT_TRUE(callback.invoked()); 358 ASSERT_EQ(FAILURE, callback.intercepted_result_type());
263 EXPECT_EQ(net::ERR_CT_STH_PARSING_FAILED, callback.net_error()); 359 EXPECT_EQ(net::ERR_CT_STH_PARSING_FAILED, callback.net_error());
360 EXPECT_EQ(net::HTTP_OK, callback.http_response_code());
264 } 361 }
265 362
266 TEST_F(LogProofFetcherTest, TestLogReplyIsTooLong) { 363 TEST_F(LogProofFetcherTest, TestLogReplyIsTooLong) {
267 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson(); 364 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson();
268 // Add kMaxLogResponseSizeInBytes to make sure the response is too big. 365 // Add kMaxLogResponseSizeInBytes to make sure the response is too big.
269 sth_json_reply_data.append( 366 sth_json_reply_data.append(
270 std::string(LogProofFetcher::kMaxLogResponseSizeInBytes, ' ')); 367 std::string(LogProofFetcher::kMaxLogResponseSizeInBytes, ' '));
271 handler_->set_response_body(sth_json_reply_data); 368 handler_->set_response_body(sth_json_reply_data);
369 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
272 370
273 RecordFetchCallbackInvocations callback(false); 371 RecordFetchCallbackInvocations callback(false);
274 RunFetcherWithCallback(&callback); 372 RunFetcherWithCallback(&callback);
275 373
276 ASSERT_TRUE(callback.invoked()); 374 ASSERT_EQ(FAILURE, callback.intercepted_result_type());
277 EXPECT_EQ(net::ERR_FILE_TOO_BIG, callback.net_error()); 375 EXPECT_EQ(net::ERR_FILE_TOO_BIG, callback.net_error());
278 EXPECT_EQ(net::HTTP_OK, callback.http_response_code()); 376 EXPECT_EQ(net::HTTP_OK, callback.http_response_code());
279 } 377 }
280 378
281 TEST_F(LogProofFetcherTest, TestLogReplyIsExactlyMaxSize) { 379 TEST_F(LogProofFetcherTest, TestLogReplyIsExactlyMaxSize) {
282 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson(); 380 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson();
283 // Extend the reply to be exactly kMaxLogResponseSizeInBytes. 381 // Extend the reply to be exactly kMaxLogResponseSizeInBytes.
284 sth_json_reply_data.append(std::string( 382 sth_json_reply_data.append(std::string(
285 LogProofFetcher::kMaxLogResponseSizeInBytes - sth_json_reply_data.size(), 383 LogProofFetcher::kMaxLogResponseSizeInBytes - sth_json_reply_data.size(),
286 ' ')); 384 ' '));
287 handler_->set_response_body(sth_json_reply_data); 385 handler_->set_response_body(sth_json_reply_data);
386 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
288 387
289 RecordFetchCallbackInvocations callback(true); 388 RecordFetchCallbackInvocations callback(true);
290 RunFetcherWithCallback(&callback); 389 RunFetcherWithCallback(&callback);
291 390
292 ASSERT_TRUE(callback.invoked()); 391 ASSERT_EQ(STH_FETCH, callback.intercepted_result_type());
392 VerifyReceivedSTH(callback.intercepted_log_id(), callback.intercepted_sth());
293 } 393 }
294 394
295 TEST_F(LogProofFetcherTest, TestLogRepliesWithHttpError) { 395 TEST_F(LogProofFetcherTest, TestLogRepliesWithHttpError) {
296 handler_->set_response_headers( 396 handler_->set_response_headers(std::string(
297 std::string(kGetSTHNotFoundHeaders, arraysize(kGetSTHNotFoundHeaders))); 397 kGetResponseNotFoundHeaders, arraysize(kGetResponseNotFoundHeaders)));
398 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
298 399
299 RecordFetchCallbackInvocations callback(false); 400 RecordFetchCallbackInvocations callback(false);
300 RunFetcherWithCallback(&callback); 401 RunFetcherWithCallback(&callback);
301 402
302 ASSERT_TRUE(callback.invoked()); 403 ASSERT_EQ(FAILURE, callback.intercepted_result_type());
303 EXPECT_EQ(net::OK, callback.net_error()); 404 EXPECT_EQ(net::OK, callback.net_error());
304 EXPECT_EQ(net::HTTP_NOT_FOUND, callback.http_response_code()); 405 EXPECT_EQ(net::HTTP_NOT_FOUND, callback.http_response_code());
305 } 406 }
306 407
408 TEST_F(LogProofFetcherTest, TestValidGetConsistencyValidReply) {
409 std::vector<std::string> proof;
410 for (uint64_t i = 0; i < kDummyConsistencyProofNumNodes; ++i)
411 proof.push_back(GetDummyConsistencyProofNode(i));
412
413 std::string consistency_proof_reply_data =
414 net::ct::CreateConsistencyProofJsonString(proof);
415 handler_->set_response_body(consistency_proof_reply_data);
416
417 RecordFetchCallbackInvocations callback(true);
418 RunGetConsistencyFetcherWithCallback(&callback);
419
420 ASSERT_EQ(CONSISTENCY_PROOF_FETCH, callback.intercepted_result_type());
421 VerifyConsistencyProof(callback.intercepted_log_id(),
422 callback.intercepted_proof());
423 }
424
425 TEST_F(LogProofFetcherTest, TestInvalidGetConsistencyReplyInvalidJSON) {
426 std::string consistency_proof_reply_data = "{\"consistency\": [1,2]}";
427 handler_->set_response_body(consistency_proof_reply_data);
428
429 RecordFetchCallbackInvocations callback(false);
430 RunGetConsistencyFetcherWithCallback(&callback);
431
432 ASSERT_EQ(FAILURE, callback.intercepted_result_type());
433 EXPECT_EQ(net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED, callback.net_error());
434 EXPECT_EQ(net::HTTP_OK, callback.http_response_code());
435 }
436
307 } // namespace 437 } // namespace
308 438
309 } // namespace certificate_transparency 439 } // namespace certificate_transparency
OLDNEW
« no previous file with comments | « components/certificate_transparency/log_proof_fetcher.cc ('k') | net/base/net_error_list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698