Coverage for /Syzygy/kasko/kasko_upload_app.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
0.0%00112.C++source

Line-by-line coverage:

   1    :  // Copyright 2016 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include "syzygy/kasko/kasko_upload_app.h"
  16    :  
  17    :  #include "base/bind.h"
  18    :  #include "base/files/file_util.h"
  19    :  #include "syzygy/kasko/crash_keys_serialization.h"
  20    :  #include "syzygy/kasko/reporter.h"
  21    :  
  22  m :  namespace kasko {
  23    :  
  24  m :  namespace {
  25    :  
  26    :  // URL of the default crash handler.
  27    :  #define KASKO_DEFAULT_UPLOAD_URL "https://clients2.google.com/cr/report"
  28    :  
  29  m :  const char kUsageFormatStr[] =
  30  m :      "Usage: %ls --minidump=<MINIDUMP> [options]\n"
  31  m :      "\n"
  32  m :      "  A tool that uploads minidumps and crashkeys to a crash server.\n"
  33  m :      "\n"
  34  m :      "Required parameters\n"
  35  m :      "  --minidump=<MINIDUMP>"
  36  m :      "    Path to the minidump file to upload.\n"
  37  m :      "\n"
  38  m :      "Optional parameters\n"
  39  m :      "  --crash-keys=<CRASHKEYS>\n"
  40  m :      "    Path to the JSON formatted crash keys to upload. Defaults to the\n"
  41  m :      "    filename obtained by replacing the minidump extension with .kys.\n"
  42  m :      "  --upload-url=<URL>\n"
  43  m :      "    URL where the crash should be upload. Defaults to:\n"
  44  m :      "    " KASKO_DEFAULT_UPLOAD_URL "\n"
  45  m :      "\n";
  46    :  
  47    :  // Callback that is invoked upon successful upload.
  48  m :  void OnUploadCallback(
  49  m :      base::string16* output_report_id,
  50  m :      const base::string16& report_id,
  51  m :      const base::FilePath& minidump_path,
  52  m :      const std::map<base::string16, base::string16>& crash_keys) {
  53  m :    DCHECK_NE(static_cast<base::string16*>(nullptr), output_report_id);
  54  m :    *output_report_id = report_id;
  55  m :  }
  56    :  
  57  m :  }  // namespace
  58    :  
  59    :  #define KASKO_MINIDUMP_SWITCH "minidump"
  60    :  
  61    :  // A small helper macro for converting an 8-bit char string to a 16-bit char
  62    :  // string.
  63    :  #define WIDEN_IMPL(x) L ## x
  64    :  #define WIDEN(x) WIDEN_IMPL(x)
  65    :  
  66  m :  const char KaskoUploadApp::kMinidumpSwitch[] = KASKO_MINIDUMP_SWITCH;
  67  m :  const char KaskoUploadApp::kCrashKeysSwitch[] = "crash-keys";
  68  m :  const char KaskoUploadApp::kUploadUrlSwitch[] = "upload-url";
  69  m :  const base::char16 KaskoUploadApp::kDefaultUploadUrl[] =
  70  m :      WIDEN(KASKO_DEFAULT_UPLOAD_URL);
  71    :  
  72  m :  KaskoUploadApp::KaskoUploadApp()
  73  m :      : application::AppImplBase("Kasko Upload") {
  74  m :  }
  75    :  
  76  m :  bool KaskoUploadApp::ParseCommandLine(const base::CommandLine* command_line) {
  77  m :    DCHECK_NE(static_cast<base::CommandLine*>(nullptr), command_line);
  78    :  
  79  m :    if (!command_line->HasSwitch(kMinidumpSwitch)) {
  80  m :      PrintUsage(command_line->GetProgram(),
  81  m :                 "You must specify --" KASKO_MINIDUMP_SWITCH ".");
  82  m :      return false;
  83  m :    }
  84    :  
  85  m :    minidump_path_ = command_line->GetSwitchValuePath(kMinidumpSwitch);
  86  m :    LOG(INFO) << "Using minidump path: " << minidump_path_.value();
  87    :  
  88  m :    if (command_line->HasSwitch(kCrashKeysSwitch)) {
  89  m :      crash_keys_path_ = command_line->GetSwitchValuePath(kCrashKeysSwitch);
  90  m :      LOG(INFO) << "Using crash-keys path: " << crash_keys_path_.value();
  91  m :    } else {
  92  m :      crash_keys_path_ = minidump_path_.ReplaceExtension(L".kys");
  93  m :      LOG(INFO) << "Using default crash-keys path: " << crash_keys_path_.value();
  94  m :    }
  95    :  
  96  m :    if (command_line->HasSwitch(kUploadUrlSwitch)) {
  97  m :      upload_url_ = command_line->GetSwitchValueNative(kUploadUrlSwitch);
  98  m :      LOG(INFO) << "Using upload URL: " << upload_url_;
  99  m :    } else {
 100  m :      upload_url_ = kDefaultUploadUrl;
 101  m :      LOG(INFO) << "Using default upload URL: " << upload_url_;
 102  m :    }
 103    :  
 104  m :    return true;
 105  m :  }
 106    :  
 107  m :  int KaskoUploadApp::Run() {
 108  m :    if (!base::PathExists(crash_keys_path_)) {
 109  m :      LOG(ERROR) << "Crash keys file not found: " << crash_keys_path_.value();
 110  m :      return kReturnCodeCrashKeysFileMissing;
 111  m :    }
 112    :  
 113  m :    std::map<base::string16, base::string16> crash_keys;
 114  m :    if (!ReadCrashKeysFromFile(crash_keys_path_, &crash_keys)) {
 115  m :      LOG(ERROR) << "Failed to read crash keys from file: "
 116  m :                 << crash_keys_path_.value();
 117  m :      return kReturnCodeCrashKeysFileMalformed;
 118  m :    }
 119    :  
 120  m :    for (const auto& kv : crash_keys) {
 121  m :      LOG(INFO) << "Read crash key \"" << kv.first << "\": \"" << kv.second
 122  m :                << "\"";
 123  m :    }
 124    :  
 125    :    // Ensure that the minimum set of necessary crash keys is present.
 126  m :    static const base::char16* kRequiredCrashKeys[] = {
 127  m :      L"prod", L"ver", L"platform", L"ptype", L"guid", L"channel" };
 128  m :    size_t missing_keys = 0;
 129  m :    for (size_t i = 0; i < arraysize(kRequiredCrashKeys); ++i) {
 130  m :      if (crash_keys.count(kRequiredCrashKeys[i]) == 0) {
 131  m :        ++missing_keys;
 132  m :        LOG(ERROR) << "Missing required crash key \"" << kRequiredCrashKeys[i]
 133  m :                   << "\".";
 134  m :      }
 135  m :    }
 136  m :    if (missing_keys > 0)
 137  m :      return kReturnCodeCrashKeysAbsent;
 138    :  
 139  m :    if (!base::PathExists(minidump_path_)) {
 140  m :      LOG(ERROR) << "Minidump file not found: " << minidump_path_.value();
 141  m :      return kReturnCodeMinidumpFileMissing;
 142  m :    }
 143    :  
 144  m :    base::string16 report_id;
 145  m :    Reporter::OnUploadCallback on_upload = base::Bind(
 146  m :        &OnUploadCallback, base::Unretained(&report_id));
 147  m :    if (!Reporter::UploadCrashReport(on_upload, upload_url_, minidump_path_,
 148  m :                                     crash_keys)) {
 149  m :      LOG(ERROR) << "Failed to upload crash report.";
 150  m :      return kReturnCodeUploadFailed;
 151  m :    }
 152    :  
 153  m :    LOG(INFO) << "Report successfully uploaded with report ID: " << report_id;
 154  m :    return kReturnCodeSuccess;
 155  m :  }
 156    :  
 157  m :  void KaskoUploadApp::PrintUsage(const base::FilePath& program,
 158  m :                                  const base::StringPiece& message) {
 159    :  
 160  m :    if (!message.empty()) {
 161  m :      ::fwrite(message.data(), 1, message.length(), out());
 162  m :      ::fprintf(out(), "\n\n");
 163  m :    }
 164    :  
 165  m :    ::fprintf(out(), kUsageFormatStr, program.BaseName().value().c_str());
 166  m :  }
 167    :  
 168  m :  }  // namespace kasko

Coverage information generated Fri Jul 29 11:00:21 2016.