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

Side by Side Diff: base/test/launcher/test_results_tracker.cc

Issue 2592923002: Keep track of output_snippet bytes and drop output snippets if output is too large
Patch Set: Created 4 years 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "base/test/launcher/test_results_tracker.h" 5 #include "base/test/launcher/test_results_tracker.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 "had unknown result"); 294 "had unknown result");
295 295
296 fprintf(stdout, "End of the summary.\n"); 296 fprintf(stdout, "End of the summary.\n");
297 fflush(stdout); 297 fflush(stdout);
298 } 298 }
299 299
300 void TestResultsTracker::AddGlobalTag(const std::string& tag) { 300 void TestResultsTracker::AddGlobalTag(const std::string& tag) {
301 global_tags_.insert(tag); 301 global_tags_.insert(tag);
302 } 302 }
303 303
304 // Sets output_snippet-related fields in test_result_value.
305 // Does not take ownership of test_result_value.
306 // Returns the number of bytes of snippet data that were added to
307 // test_result_value.
308 int SetSnippets(StringPiece output_snippet,
309 DictionaryValue* test_result_value) {
310 int num_bytes = 0;
311 // Always include the raw version (base64-encoded so that it can be safely
312 // JSON-serialized - there are no guarantees about character encoding of the
313 // snippet). This can be very useful piece of information when debugging a
314 // test failure related to character encoding.
315 std::string base64;
316 Base64Encode(output_snippet, &base64);
317 test_result_value->SetString("output_snippet_base64", base64);
318 num_bytes += base64.size();
319
320 bool lossless_snippet = false;
321 if (IsStringUTF8(output_snippet)) {
322 lossless_snippet = true;
323 } else {
324 output_snippet = "<non-UTF-8 snippet, see output_snippet_base64>";
325 }
326
327 test_result_value->SetString("output_snippet", output_snippet);
328 num_bytes += output_snippet.size();
329
330 // TODO(phajdan.jr): Fix typo in JSON key (losless -> lossless)
331 // making sure not to break any consumers of this data.
332 test_result_value->SetBoolean("losless_snippet", lossless_snippet);
333
334 return num_bytes;
335 }
336
337 // This is the maximum output.json which can be handled by
338 // build/scripts/slave/recipe_modules/swarming/resources/collect_gtest_task.py
339 // SaveSummaryAsJSON does not strictly ensure that its output is below this
340 // threshold, but it will attempt to avoid exceeding this maximum by dropping
341 // output_snippets as the total output approaches this threshold.
342 const int kMaxSummaryJSON = 100 * 1024 * 1024;
343
304 bool TestResultsTracker::SaveSummaryAsJSON( 344 bool TestResultsTracker::SaveSummaryAsJSON(
305 const FilePath& path, 345 const FilePath& path,
306 const std::vector<std::string>& additional_tags) const { 346 const std::vector<std::string>& additional_tags) const {
307 std::unique_ptr<DictionaryValue> summary_root(new DictionaryValue); 347 std::unique_ptr<DictionaryValue> summary_root(new DictionaryValue);
308 348
309 std::unique_ptr<ListValue> global_tags(new ListValue); 349 std::unique_ptr<ListValue> global_tags(new ListValue);
310 for (const auto& global_tag : global_tags_) { 350 for (const auto& global_tag : global_tags_) {
311 global_tags->AppendString(global_tag); 351 global_tags->AppendString(global_tag);
312 } 352 }
313 for (const auto& tag : additional_tags) { 353 for (const auto& tag : additional_tags) {
314 global_tags->AppendString(tag); 354 global_tags->AppendString(tag);
315 } 355 }
316 summary_root->Set("global_tags", std::move(global_tags)); 356 summary_root->Set("global_tags", std::move(global_tags));
317 357
318 std::unique_ptr<ListValue> all_tests(new ListValue); 358 std::unique_ptr<ListValue> all_tests(new ListValue);
319 for (const auto& test : all_tests_) { 359 for (const auto& test : all_tests_) {
320 all_tests->AppendString(test); 360 all_tests->AppendString(test);
321 } 361 }
322 summary_root->Set("all_tests", std::move(all_tests)); 362 summary_root->Set("all_tests", std::move(all_tests));
323 363
324 std::unique_ptr<ListValue> disabled_tests(new ListValue); 364 std::unique_ptr<ListValue> disabled_tests(new ListValue);
325 for (const auto& disabled_test : disabled_tests_) { 365 for (const auto& disabled_test : disabled_tests_) {
326 disabled_tests->AppendString(disabled_test); 366 disabled_tests->AppendString(disabled_test);
327 } 367 }
328 summary_root->Set("disabled_tests", std::move(disabled_tests)); 368 summary_root->Set("disabled_tests", std::move(disabled_tests));
329 369
330 std::unique_ptr<ListValue> per_iteration_data(new ListValue); 370 std::unique_ptr<ListValue> per_iteration_data(new ListValue);
331 371
372 // Keep track of the number of bytes used by the contents of output snippets.
373 // Once we use up half of the maxium output size, we will start dropping
374 // snippets.
375 int snippet_bytes = 0;
376 int snippet_byte_threshold = kMaxSummaryJSON / 2;
377
332 for (int i = 0; i <= iteration_; i++) { 378 for (int i = 0; i <= iteration_; i++) {
333 std::unique_ptr<DictionaryValue> current_iteration_data( 379 std::unique_ptr<DictionaryValue> current_iteration_data(
334 new DictionaryValue); 380 new DictionaryValue);
335 381
336 for (PerIterationData::ResultsMap::const_iterator j = 382 for (PerIterationData::ResultsMap::const_iterator j =
337 per_iteration_data_[i].results.begin(); 383 per_iteration_data_[i].results.begin();
338 j != per_iteration_data_[i].results.end(); 384 j != per_iteration_data_[i].results.end();
339 ++j) { 385 ++j) {
340 std::unique_ptr<ListValue> test_results(new ListValue); 386 std::unique_ptr<ListValue> test_results(new ListValue);
341 387
342 for (size_t k = 0; k < j->second.test_results.size(); k++) { 388 for (size_t k = 0; k < j->second.test_results.size(); k++) {
343 const TestResult& test_result = j->second.test_results[k]; 389 const TestResult& test_result = j->second.test_results[k];
344 390
345 std::unique_ptr<DictionaryValue> test_result_value(new DictionaryValue); 391 std::unique_ptr<DictionaryValue> test_result_value(new DictionaryValue);
346 392
347 test_result_value->SetString("status", test_result.StatusAsString()); 393 test_result_value->SetString("status", test_result.StatusAsString());
348 test_result_value->SetInteger( 394 test_result_value->SetInteger(
349 "elapsed_time_ms", 395 "elapsed_time_ms",
350 static_cast<int>(test_result.elapsed_time.InMilliseconds())); 396 static_cast<int>(test_result.elapsed_time.InMilliseconds()));
351 397
352 bool lossless_snippet = false; 398 StringPiece snippet = snippet_bytes > snippet_byte_threshold
353 if (IsStringUTF8(test_result.output_snippet)) { 399 ? "lengthy output elided"
Paweł Hajdan Jr. 2016/12/22 14:18:39 I'm concerned this seems to result in a silent fai
354 test_result_value->SetString( 400 : test_result.output_snippet;
355 "output_snippet", test_result.output_snippet); 401 snippet_bytes += SetSnippets(snippet, test_result_value.get());
356 lossless_snippet = true;
357 } else {
358 test_result_value->SetString(
359 "output_snippet",
360 "<non-UTF-8 snippet, see output_snippet_base64>");
361 }
362 402
363 // TODO(phajdan.jr): Fix typo in JSON key (losless -> lossless)
364 // making sure not to break any consumers of this data.
365 test_result_value->SetBoolean("losless_snippet", lossless_snippet);
366
367 // Also include the raw version (base64-encoded so that it can be safely
368 // JSON-serialized - there are no guarantees about character encoding
369 // of the snippet). This can be very useful piece of information when
370 // debugging a test failure related to character encoding.
371 std::string base64_output_snippet;
372 Base64Encode(test_result.output_snippet, &base64_output_snippet);
373 test_result_value->SetString("output_snippet_base64",
374 base64_output_snippet);
375 test_results->Append(std::move(test_result_value)); 403 test_results->Append(std::move(test_result_value));
376 } 404 }
377 405
378 current_iteration_data->SetWithoutPathExpansion(j->first, 406 current_iteration_data->SetWithoutPathExpansion(j->first,
379 std::move(test_results)); 407 std::move(test_results));
380 } 408 }
381 per_iteration_data->Append(std::move(current_iteration_data)); 409 per_iteration_data->Append(std::move(current_iteration_data));
382 } 410 }
383 summary_root->Set("per_iteration_data", std::move(per_iteration_data)); 411 summary_root->Set("per_iteration_data", std::move(per_iteration_data));
384 412
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 TestResultsTracker::PerIterationData::PerIterationData() { 491 TestResultsTracker::PerIterationData::PerIterationData() {
464 } 492 }
465 493
466 TestResultsTracker::PerIterationData::PerIterationData( 494 TestResultsTracker::PerIterationData::PerIterationData(
467 const PerIterationData& other) = default; 495 const PerIterationData& other) = default;
468 496
469 TestResultsTracker::PerIterationData::~PerIterationData() { 497 TestResultsTracker::PerIterationData::~PerIterationData() {
470 } 498 }
471 499
472 } // namespace base 500 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698