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

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: Switching to simpler callbacks model Created 4 years, 11 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
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 // Node returned will be chr(node_id) * 32.
46 std::string GetDummyConsistencyProofNode(uint64_t node_id) {
47 return std::string(32, static_cast<char>(node_id));
48 }
Ryan Sleevi 2016/01/23 00:34:23 This comment/function is not really clear. Why the
Eran Messeri 2016/01/25 17:07:38 Done.
49
50 const size_t kDummyConsistencyProofLength = 4;
Ryan Sleevi 2016/01/23 00:34:23 This needs documentation. In looking how it's used
Eran Messeri 2016/01/25 17:07:38 I agree it's non-obvious what this value is for in
51
52 class LogFetchTestJob : public net::URLRequestTestJob {
44 public: 53 public:
45 FetchSTHTestJob(const std::string& get_sth_data, 54 LogFetchTestJob(const std::string& get_log_data,
46 const std::string& get_sth_headers, 55 const std::string& get_log_headers,
47 net::URLRequest* request, 56 net::URLRequest* request,
48 net::NetworkDelegate* network_delegate) 57 net::NetworkDelegate* network_delegate)
49 : URLRequestTestJob(request, 58 : URLRequestTestJob(request,
50 network_delegate, 59 network_delegate,
51 get_sth_headers, 60 get_log_headers,
52 get_sth_data, 61 get_log_data,
53 true), 62 true),
54 async_io_(false) {} 63 async_io_(false) {}
55 64
56 void set_async_io(bool async_io) { async_io_ = async_io; } 65 void set_async_io(bool async_io) { async_io_ = async_io; }
57 66
58 private: 67 private:
59 ~FetchSTHTestJob() override {} 68 ~LogFetchTestJob() override {}
60 69
61 bool NextReadAsync() override { 70 bool NextReadAsync() override {
62 // Response with indication of async IO only once, otherwise the final 71 // Response with indication of async IO only once, otherwise the final
63 // Read would (incorrectly) be classified as async, causing the 72 // Read would (incorrectly) be classified as async, causing the
64 // URLRequestJob to try reading another time and failing on a CHECK 73 // URLRequestJob to try reading another time and failing on a CHECK
65 // that the raw_read_buffer_ is not null. 74 // that the raw_read_buffer_ is not null.
66 // According to mmenke@, this is a bug in the URLRequestTestJob code. 75 // 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 76 // TODO(eranm): Once said bug is fixed, switch most tests to using async
68 // IO. 77 // IO.
69 if (async_io_) { 78 if (async_io_) {
70 async_io_ = false; 79 async_io_ = false;
71 return true; 80 return true;
72 } 81 }
73 return false; 82 return false;
74 } 83 }
75 84
76 bool async_io_; 85 bool async_io_;
77 86
78 DISALLOW_COPY_AND_ASSIGN(FetchSTHTestJob); 87 DISALLOW_COPY_AND_ASSIGN(LogFetchTestJob);
79 }; 88 };
80 89
81 class GetSTHResponseHandler : public net::URLRequestInterceptor { 90 class LogGetResponseHandler : public net::URLRequestInterceptor {
82 public: 91 public:
83 GetSTHResponseHandler() 92 LogGetResponseHandler()
84 : async_io_(false), 93 : async_io_(false),
85 response_body_(""),
86 response_headers_( 94 response_headers_(
87 std::string(kGetSTHHeaders, arraysize(kGetSTHHeaders))) {} 95 std::string(kGetResponseHeaders, arraysize(kGetResponseHeaders))) {}
88 ~GetSTHResponseHandler() override {} 96 ~LogGetResponseHandler() override {}
89 97
90 // URLRequestInterceptor implementation: 98 // URLRequestInterceptor implementation:
91 net::URLRequestJob* MaybeInterceptRequest( 99 net::URLRequestJob* MaybeInterceptRequest(
92 net::URLRequest* request, 100 net::URLRequest* request,
93 net::NetworkDelegate* network_delegate) const override { 101 net::NetworkDelegate* network_delegate) const override {
94 std::string expected_url = base::StringPrintf( 102 EXPECT_EQ(expected_url_, request->url());
95 "%s://%s/%s/ct/v1/get-sth", kLogSchema, kLogHost, kLogPathPrefix); 103
96 EXPECT_EQ(GURL(expected_url), request->url()); 104 LogFetchTestJob* job = new LogFetchTestJob(
97 FetchSTHTestJob* job = new FetchSTHTestJob(
98 response_body_, response_headers_, request, network_delegate); 105 response_body_, response_headers_, request, network_delegate);
99 job->set_async_io(async_io_); 106 job->set_async_io(async_io_);
100 return job; 107 return job;
101 } 108 }
102 109
103 void set_response_body(const std::string& response_body) { 110 void set_response_body(const std::string& response_body) {
104 response_body_ = response_body; 111 response_body_ = response_body;
105 } 112 }
106 113
107 void set_response_headers(const std::string& response_headers) { 114 void set_response_headers(const std::string& response_headers) {
108 response_headers_ = response_headers; 115 response_headers_ = response_headers;
109 } 116 }
110 117
111 void set_async_io(bool async_io) { async_io_ = async_io; } 118 void set_async_io(bool async_io) { async_io_ = async_io; }
112 119
120 void set_expected_url(const GURL& url) { expected_url_ = url; }
121
113 private: 122 private:
114 bool async_io_; 123 bool async_io_;
115 std::string response_body_; 124 std::string response_body_;
116 std::string response_headers_; 125 std::string response_headers_;
117 126
118 DISALLOW_COPY_AND_ASSIGN(GetSTHResponseHandler); 127 // Stored for test body to assert on
128 GURL expected_url_;
129
130 DISALLOW_COPY_AND_ASSIGN(LogGetResponseHandler);
131 };
132
133 enum InterceptedResultType {
134 NOTHING,
135 FAILURE,
136 STH_FETCH,
137 CONSISTENCY_PROOF_FETCH
119 }; 138 };
120 139
121 class RecordFetchCallbackInvocations { 140 class RecordFetchCallbackInvocations {
122 public: 141 public:
123 RecordFetchCallbackInvocations(bool expect_success) 142 RecordFetchCallbackInvocations(bool expect_success)
124 : expect_success_(expect_success), 143 : expect_success_(expect_success),
125 invoked_(false),
126 net_error_(net::OK), 144 net_error_(net::OK),
127 http_response_code_(-1) {} 145 http_response_code_(-1),
146 request_type_(NOTHING) {}
128 147
129 void STHFetched(const std::string& log_id, 148 void STHFetched(base::Closure quit_closure,
149 const std::string& log_id,
130 const net::ct::SignedTreeHead& sth) { 150 const net::ct::SignedTreeHead& sth) {
131 ASSERT_TRUE(expect_success_); 151 ASSERT_TRUE(expect_success_);
132 ASSERT_FALSE(invoked_); 152 ASSERT_EQ(NOTHING, request_type_);
133 invoked_ = true; 153 request_type_ = STH_FETCH;
134 // If expected to succeed, expecting the known_good STH. 154 sth_ = sth;
135 net::ct::SignedTreeHead expected_sth; 155 log_id_ = log_id;
136 net::ct::GetSampleSignedTreeHead(&expected_sth); 156 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 } 157 }
150 158
151 void FetchingFailed(const std::string& log_id, 159 void ConsistencyProofFetched(
160 base::Closure quit_closure,
161 const std::string& log_id,
162 const std::vector<std::string>& consistency_proof) {
163 ASSERT_TRUE(expect_success_);
164 ASSERT_EQ(NOTHING, request_type_);
165 request_type_ = CONSISTENCY_PROOF_FETCH;
166 consistency_proof_.assign(consistency_proof.begin(),
167 consistency_proof.end());
168 log_id_ = log_id;
169 quit_closure.Run();
170 }
171
172 void FetchingFailed(base::Closure quit_closure,
173 const std::string& log_id,
152 int net_error, 174 int net_error,
153 int http_response_code) { 175 int http_response_code) {
154 ASSERT_FALSE(expect_success_); 176 ASSERT_FALSE(expect_success_);
155 ASSERT_FALSE(invoked_); 177 ASSERT_EQ(NOTHING, request_type_);
156 invoked_ = true; 178 request_type_ = FAILURE;
157 net_error_ = net_error; 179 net_error_ = net_error;
158 http_response_code_ = http_response_code; 180 http_response_code_ = http_response_code;
159 if (net_error_ == net::OK) { 181 if (net_error_ == net::OK) {
160 EXPECT_NE(net::HTTP_OK, http_response_code_); 182 EXPECT_NE(net::HTTP_OK, http_response_code_);
161 } 183 }
184
185 quit_closure.Run();
162 } 186 }
163 187
164 bool invoked() const { return invoked_; } 188 InterceptedResultType intercepted_result_type() const {
189 return request_type_;
190 }
165 191
166 int net_error() const { return net_error_; } 192 int net_error() const { return net_error_; }
167 193
168 int http_response_code() const { return http_response_code_; } 194 int http_response_code() const { return http_response_code_; }
169 195
196 const net::ct::SignedTreeHead& intercepted_sth() const { return sth_; }
197
198 const std::string& intercepted_log_id() const { return log_id_; }
199
200 const std::vector<std::string>& intercepted_proof() const {
201 return consistency_proof_;
202 }
203
170 private: 204 private:
171 const bool expect_success_; 205 const bool expect_success_;
172 bool invoked_;
173 int net_error_; 206 int net_error_;
174 int http_response_code_; 207 int http_response_code_;
208 InterceptedResultType request_type_;
209 net::ct::SignedTreeHead sth_;
210 std::string log_id_;
211 std::vector<std::string> consistency_proof_;
175 }; 212 };
176 213
177 class LogProofFetcherTest : public ::testing::Test { 214 class LogProofFetcherTest : public ::testing::Test {
178 public: 215 public:
179 LogProofFetcherTest() 216 LogProofFetcherTest()
180 : log_url_(base::StringPrintf("%s://%s/%s/", 217 : log_url_(base::StringPrintf("%s://%s/%s/",
181 kLogSchema, 218 kLogSchema,
182 kLogHost, 219 kLogHost,
183 kLogPathPrefix)) { 220 kLogPathPrefix)) {
184 scoped_ptr<GetSTHResponseHandler> handler(new GetSTHResponseHandler()); 221 scoped_ptr<LogGetResponseHandler> handler(new LogGetResponseHandler());
185 handler_ = handler.get(); 222 handler_ = handler.get();
186 223
187 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( 224 net::URLRequestFilter::GetInstance()->AddHostnameInterceptor(
188 kLogSchema, kLogHost, std::move(handler)); 225 kLogSchema, kLogHost, std::move(handler));
189 226
190 fetcher_.reset(new LogProofFetcher(&context_)); 227 fetcher_.reset(new LogProofFetcher(&context_));
191 } 228 }
192 229
193 ~LogProofFetcherTest() override { 230 ~LogProofFetcherTest() override {
194 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(kLogSchema, 231 net::URLRequestFilter::GetInstance()->RemoveHostnameHandler(kLogSchema,
195 kLogHost); 232 kLogHost);
196 } 233 }
197 234
198 protected: 235 protected:
199 void SetValidSTHJSONResponse() { 236 void SetValidSTHJSONResponse() {
200 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson(); 237 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson();
201 handler_->set_response_body(sth_json_reply_data); 238 handler_->set_response_body(sth_json_reply_data);
239 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
202 } 240 }
203 241
204 void RunFetcherWithCallback(RecordFetchCallbackInvocations* callback) { 242 void RunFetcherWithCallback(RecordFetchCallbackInvocations* callback) {
205 fetcher_->FetchSignedTreeHead( 243 fetcher_->FetchSignedTreeHead(
206 log_url_, kLogID, 244 log_url_, kLogID,
207 base::Bind(&RecordFetchCallbackInvocations::STHFetched, 245 base::Bind(&RecordFetchCallbackInvocations::STHFetched,
208 base::Unretained(callback)), 246 base::Unretained(callback), run_loop_.QuitClosure()),
209 base::Bind(&RecordFetchCallbackInvocations::FetchingFailed, 247 base::Bind(&RecordFetchCallbackInvocations::FetchingFailed,
210 base::Unretained(callback))); 248 base::Unretained(callback), run_loop_.QuitClosure()));
211 message_loop_.RunUntilIdle(); 249 run_loop_.Run();
212 } 250 }
213 251
252 void RunGetConsistencyFetcherWithCallback(
253 RecordFetchCallbackInvocations* callback) {
254 const uint64_t kOldTree = 5;
255 const uint64_t kNewTree = 8;
256 handler_->set_expected_url(log_url_.Resolve(base::StringPrintf(
257 "ct/v1/get-sth-consistency?first=%" PRIu64 "&second=%" PRIu64, kOldTree,
258 kNewTree)));
259 fetcher_->FetchConsistencyProof(
260 log_url_, kLogID, kOldTree, kNewTree,
261 base::Bind(&RecordFetchCallbackInvocations::ConsistencyProofFetched,
262 base::Unretained(callback), run_loop_.QuitClosure()),
263 base::Bind(&RecordFetchCallbackInvocations::FetchingFailed,
264 base::Unretained(callback), run_loop_.QuitClosure()));
265 run_loop_.Run();
266 }
267
268 void VerifyReceivedSTH(const std::string& log_id,
269 const net::ct::SignedTreeHead& sth) {
270 net::ct::SignedTreeHead expected_sth;
271 net::ct::GetSampleSignedTreeHead(&expected_sth);
272
273 EXPECT_EQ(kLogID, log_id);
274 EXPECT_EQ(expected_sth.version, sth.version);
275 EXPECT_EQ(expected_sth.timestamp, sth.timestamp);
276 EXPECT_EQ(expected_sth.tree_size, sth.tree_size);
277 EXPECT_STREQ(expected_sth.sha256_root_hash, sth.sha256_root_hash);
278 EXPECT_EQ(expected_sth.signature.hash_algorithm,
279 sth.signature.hash_algorithm);
280 EXPECT_EQ(expected_sth.signature.signature_algorithm,
281 sth.signature.signature_algorithm);
282 EXPECT_EQ(expected_sth.signature.signature_data,
283 sth.signature.signature_data);
284 }
285
286 void VerifyConsistencyProof(
287 const std::string& log_id,
288 const std::vector<std::string>& consistency_proof) {
289 EXPECT_EQ(kLogID, log_id);
290 EXPECT_EQ(kDummyConsistencyProofLength, consistency_proof.size());
291 for (uint64_t i = 0; i < kDummyConsistencyProofLength; ++i) {
292 EXPECT_EQ(GetDummyConsistencyProofNode(i), consistency_proof[i])
293 << " node: " << i;
294 }
295 }
296
297 // The |message_loop_|, while seemingly unused, is necessary
298 // for URL request interception. That is the message loop that
299 // will be used by the RunLoop.
214 base::MessageLoopForIO message_loop_; 300 base::MessageLoopForIO message_loop_;
301 base::RunLoop run_loop_;
215 net::TestURLRequestContext context_; 302 net::TestURLRequestContext context_;
216 safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_; 303 safe_json::TestingJsonParser::ScopedFactoryOverride factory_override_;
217 scoped_ptr<LogProofFetcher> fetcher_; 304 scoped_ptr<LogProofFetcher> fetcher_;
218 const GURL log_url_; 305 const GURL log_url_;
219 GetSTHResponseHandler* handler_; 306 LogGetResponseHandler* handler_;
220 }; 307 };
221 308
222 TEST_F(LogProofFetcherTest, TestValidGetReply) { 309 TEST_F(LogProofFetcherTest, TestValidGetReply) {
223 SetValidSTHJSONResponse(); 310 SetValidSTHJSONResponse();
224 311
225 RecordFetchCallbackInvocations callback(true); 312 RecordFetchCallbackInvocations callback(true);
226 313
227 RunFetcherWithCallback(&callback); 314 RunFetcherWithCallback(&callback);
228 315
229 ASSERT_TRUE(callback.invoked()); 316 ASSERT_EQ(STH_FETCH, callback.intercepted_result_type());
317 VerifyReceivedSTH(callback.intercepted_log_id(), callback.intercepted_sth());
230 } 318 }
231 319
232 TEST_F(LogProofFetcherTest, TestValidGetReplyAsyncIO) { 320 TEST_F(LogProofFetcherTest, TestValidGetReplyAsyncIO) {
233 SetValidSTHJSONResponse(); 321 SetValidSTHJSONResponse();
234 handler_->set_async_io(true); 322 handler_->set_async_io(true);
235 323
236 RecordFetchCallbackInvocations callback(true); 324 RecordFetchCallbackInvocations callback(true);
237 RunFetcherWithCallback(&callback); 325 RunFetcherWithCallback(&callback);
238 326
239 ASSERT_TRUE(callback.invoked()); 327 ASSERT_EQ(STH_FETCH, callback.intercepted_result_type());
328 VerifyReceivedSTH(callback.intercepted_log_id(), callback.intercepted_sth());
240 } 329 }
241 330
242 TEST_F(LogProofFetcherTest, TestInvalidGetReplyIncompleteJSON) { 331 TEST_F(LogProofFetcherTest, TestInvalidGetReplyIncompleteJSON) {
243 std::string sth_json_reply_data = net::ct::CreateSignedTreeHeadJsonString( 332 std::string sth_json_reply_data = net::ct::CreateSignedTreeHeadJsonString(
244 21 /* tree_size */, 123456u /* timestamp */, std::string(), 333 21 /* tree_size */, 123456u /* timestamp */, std::string(),
245 std::string()); 334 std::string());
246 handler_->set_response_body(sth_json_reply_data); 335 handler_->set_response_body(sth_json_reply_data);
336 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
247 337
248 RecordFetchCallbackInvocations callback(false); 338 RecordFetchCallbackInvocations callback(false);
249 RunFetcherWithCallback(&callback); 339 RunFetcherWithCallback(&callback);
250 340
251 ASSERT_TRUE(callback.invoked()); 341 ASSERT_EQ(FAILURE, callback.intercepted_result_type());
252 EXPECT_EQ(net::ERR_CT_STH_INCOMPLETE, callback.net_error()); 342 EXPECT_EQ(net::ERR_CT_STH_INCOMPLETE, callback.net_error());
253 } 343 }
254 344
255 TEST_F(LogProofFetcherTest, TestInvalidGetReplyInvalidJSON) { 345 TEST_F(LogProofFetcherTest, TestInvalidGetReplyInvalidJSON) {
256 std::string sth_json_reply_data = "{\"tree_size\":21,\"timestamp\":}"; 346 std::string sth_json_reply_data = "{\"tree_size\":21,\"timestamp\":}";
257 handler_->set_response_body(sth_json_reply_data); 347 handler_->set_response_body(sth_json_reply_data);
348 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
258 349
259 RecordFetchCallbackInvocations callback(false); 350 RecordFetchCallbackInvocations callback(false);
260 RunFetcherWithCallback(&callback); 351 RunFetcherWithCallback(&callback);
261 352
262 ASSERT_TRUE(callback.invoked()); 353 ASSERT_EQ(FAILURE, callback.intercepted_result_type());
263 EXPECT_EQ(net::ERR_CT_STH_PARSING_FAILED, callback.net_error()); 354 EXPECT_EQ(net::ERR_CT_STH_PARSING_FAILED, callback.net_error());
264 } 355 }
265 356
266 TEST_F(LogProofFetcherTest, TestLogReplyIsTooLong) { 357 TEST_F(LogProofFetcherTest, TestLogReplyIsTooLong) {
267 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson(); 358 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson();
268 // Add kMaxLogResponseSizeInBytes to make sure the response is too big. 359 // Add kMaxLogResponseSizeInBytes to make sure the response is too big.
269 sth_json_reply_data.append( 360 sth_json_reply_data.append(
270 std::string(LogProofFetcher::kMaxLogResponseSizeInBytes, ' ')); 361 std::string(LogProofFetcher::kMaxLogResponseSizeInBytes, ' '));
271 handler_->set_response_body(sth_json_reply_data); 362 handler_->set_response_body(sth_json_reply_data);
363 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
272 364
273 RecordFetchCallbackInvocations callback(false); 365 RecordFetchCallbackInvocations callback(false);
274 RunFetcherWithCallback(&callback); 366 RunFetcherWithCallback(&callback);
275 367
276 ASSERT_TRUE(callback.invoked()); 368 ASSERT_EQ(FAILURE, callback.intercepted_result_type());
277 EXPECT_EQ(net::ERR_FILE_TOO_BIG, callback.net_error()); 369 EXPECT_EQ(net::ERR_FILE_TOO_BIG, callback.net_error());
278 EXPECT_EQ(net::HTTP_OK, callback.http_response_code()); 370 EXPECT_EQ(net::HTTP_OK, callback.http_response_code());
279 } 371 }
280 372
281 TEST_F(LogProofFetcherTest, TestLogReplyIsExactlyMaxSize) { 373 TEST_F(LogProofFetcherTest, TestLogReplyIsExactlyMaxSize) {
282 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson(); 374 std::string sth_json_reply_data = net::ct::GetSampleSTHAsJson();
283 // Extend the reply to be exactly kMaxLogResponseSizeInBytes. 375 // Extend the reply to be exactly kMaxLogResponseSizeInBytes.
284 sth_json_reply_data.append(std::string( 376 sth_json_reply_data.append(std::string(
285 LogProofFetcher::kMaxLogResponseSizeInBytes - sth_json_reply_data.size(), 377 LogProofFetcher::kMaxLogResponseSizeInBytes - sth_json_reply_data.size(),
286 ' ')); 378 ' '));
287 handler_->set_response_body(sth_json_reply_data); 379 handler_->set_response_body(sth_json_reply_data);
380 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
288 381
289 RecordFetchCallbackInvocations callback(true); 382 RecordFetchCallbackInvocations callback(true);
290 RunFetcherWithCallback(&callback); 383 RunFetcherWithCallback(&callback);
291 384
292 ASSERT_TRUE(callback.invoked()); 385 ASSERT_EQ(STH_FETCH, callback.intercepted_result_type());
386 VerifyReceivedSTH(callback.intercepted_log_id(), callback.intercepted_sth());
293 } 387 }
294 388
295 TEST_F(LogProofFetcherTest, TestLogRepliesWithHttpError) { 389 TEST_F(LogProofFetcherTest, TestLogRepliesWithHttpError) {
296 handler_->set_response_headers( 390 handler_->set_response_headers(std::string(
297 std::string(kGetSTHNotFoundHeaders, arraysize(kGetSTHNotFoundHeaders))); 391 kGetResponseNotFoundHeaders, arraysize(kGetResponseNotFoundHeaders)));
392 handler_->set_expected_url(log_url_.Resolve("ct/v1/get-sth"));
298 393
299 RecordFetchCallbackInvocations callback(false); 394 RecordFetchCallbackInvocations callback(false);
300 RunFetcherWithCallback(&callback); 395 RunFetcherWithCallback(&callback);
301 396
302 ASSERT_TRUE(callback.invoked()); 397 ASSERT_EQ(FAILURE, callback.intercepted_result_type());
303 EXPECT_EQ(net::OK, callback.net_error()); 398 EXPECT_EQ(net::OK, callback.net_error());
304 EXPECT_EQ(net::HTTP_NOT_FOUND, callback.http_response_code()); 399 EXPECT_EQ(net::HTTP_NOT_FOUND, callback.http_response_code());
305 } 400 }
306 401
402 TEST_F(LogProofFetcherTest, TestValidGetConsistencyValidReply) {
403 std::vector<std::string> proof;
404 for (uint64_t i = 0; i < kDummyConsistencyProofLength; ++i)
405 proof.push_back(GetDummyConsistencyProofNode(i));
406
407 std::string consistency_proof_reply_data =
408 net::ct::CreateConsistencyProofJsonString(proof);
409 handler_->set_response_body(consistency_proof_reply_data);
410
411 RecordFetchCallbackInvocations callback(true);
412 RunGetConsistencyFetcherWithCallback(&callback);
413
414 ASSERT_EQ(CONSISTENCY_PROOF_FETCH, callback.intercepted_result_type());
415 VerifyConsistencyProof(callback.intercepted_log_id(),
416 callback.intercepted_proof());
417 }
418
419 TEST_F(LogProofFetcherTest, TestInvalidGetConsistencyReplyInvalidJSON) {
420 std::string consistency_proof_reply_data = "{\"consistency\": [1,2]}";
421 handler_->set_response_body(consistency_proof_reply_data);
422
423 RecordFetchCallbackInvocations callback(false);
424 RunGetConsistencyFetcherWithCallback(&callback);
425
426 ASSERT_EQ(FAILURE, callback.intercepted_result_type());
427 EXPECT_EQ(net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED, callback.net_error());
428 EXPECT_EQ(net::HTTP_OK, callback.http_response_code());
429 }
430
307 } // namespace 431 } // namespace
308 432
309 } // namespace certificate_transparency 433 } // namespace certificate_transparency
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698