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
3// found in the LICENSE file.
4
5#include "chrome/browser/diagnostics/diagnostics_metrics.h"
6
7#include <string>
8
9#include "base/basictypes.h"
10#include "base/metrics/histogram.h"
11#include "chrome/browser/diagnostics/diagnostics_test.h"
12
13namespace diagnostics {
14
15namespace {
16
17// A struct to hold information about the tests.
18struct TestNameInfo {
19  // Should only contain characters [A-Za-z0-9] (no spaces).
20  const char* name;
21
22  // A non-localized description only meant for developer consumption.
23  const char* description;
24};
25
26// This structure MUST have DIAGNOSTICS_TEST_COUNT entries in it: one for each
27// value of DiagnosticsTestId.  Note that the values in the "name" fields are
28// used for UMA metrics names (with "Diagnostics.Test." or
29// "Diagnostics.Recovery." prepended), so do not change them without
30// understanding the consequences.
31const TestNameInfo kTestNameInfo[] = {
32    {"ConflictingDlls", "Conflicting modules"},
33    {"DiskSpace", "Available disk space"},
34    {"InstallType", "Install type"},
35    {"JSONBookmarks", "Bookmark file"},
36    {"JSONLocalState", "Local state integrity"},
37    {"JSONPreferences", "User preferences integrity"},
38    {"OperatingSystem", "Operating system supported version"},
39    {"PathDictionaries", "App dictionaries directory path"},
40    {"PathLocalState", "Local state path"},
41    {"PathResources", "Resources path"},
42    {"PathUserData", "User data path"},
43    {"Version", "Chrome version test"},
44    {"SQLiteIntegrityAppCache", "Application cache database"},
45    {"SQLiteIntegrityArchivedHistory", "Archived history database (obsolete)"},
46    {"SQLiteIntegrityCookie", "Cookie database"},
47    {"SQLiteIntegrityDatabaseTracker", "Database tracker database"},
48    {"SQLiteIntegrityHistory", "History database"},
49    {"SQLiteIntegrityNSSCert", "NSS certificate database"},
50    {"SQLiteIntegrityNSSKey", "NSS Key database"},
51    {"SQLiteIntegrityThumbnails", "Thumbnails database"},
52    {"SQLiteIntegrityWebData", "Web Data database"},
53    // Add new entries in the same order as DiagnosticsTestId.
54};
55
56COMPILE_ASSERT(arraysize(kTestNameInfo) == DIAGNOSTICS_TEST_ID_COUNT,
57               diagnostics_test_info_mismatch);
58
59const TestNameInfo* FindTestInfo(DiagnosticsTestId id) {
60  DCHECK(id < DIAGNOSTICS_TEST_ID_COUNT);
61  return &kTestNameInfo[id];
62}
63
64}  // namespace
65
66std::string GetTestName(DiagnosticsTestId id) {
67  return std::string(FindTestInfo(id)->name);
68}
69
70std::string GetTestDescription(DiagnosticsTestId id) {
71  return std::string(FindTestInfo(id)->description);
72}
73
74#define TEST_CASE(name, id)                                \
75  case id:                                                 \
76    UMA_HISTOGRAM_ENUMERATION(name, result, RESULT_COUNT); \
77    break
78
79// These must each have their own complete case so that the UMA macros create
80// a unique static pointer block for each individual metric.  This is done as a
81// macro to prevent errors where the ID is added to one function below, but not
82// the other, because they must match.
83#define TEST_CASES(name)                                               \
84  TEST_CASE(name, DIAGNOSTICS_CONFLICTING_DLLS_TEST);                  \
85  TEST_CASE(name, DIAGNOSTICS_DISK_SPACE_TEST);                        \
86  TEST_CASE(name, DIAGNOSTICS_INSTALL_TYPE_TEST);                      \
87  TEST_CASE(name, DIAGNOSTICS_JSON_BOOKMARKS_TEST);                    \
88  TEST_CASE(name, DIAGNOSTICS_JSON_LOCAL_STATE_TEST);                  \
89  TEST_CASE(name, DIAGNOSTICS_JSON_PREFERENCES_TEST);                  \
90  TEST_CASE(name, DIAGNOSTICS_OPERATING_SYSTEM_TEST);                  \
91  TEST_CASE(name, DIAGNOSTICS_PATH_DICTIONARIES_TEST);                 \
92  TEST_CASE(name, DIAGNOSTICS_PATH_LOCAL_STATE_TEST);                  \
93  TEST_CASE(name, DIAGNOSTICS_PATH_RESOURCES_TEST);                    \
94  TEST_CASE(name, DIAGNOSTICS_PATH_USER_DATA_TEST);                    \
95  TEST_CASE(name, DIAGNOSTICS_VERSION_TEST);                           \
96  TEST_CASE(name, DIAGNOSTICS_SQLITE_INTEGRITY_APP_CACHE_TEST);        \
97  TEST_CASE(name, DIAGNOSTICS_SQLITE_INTEGRITY_ARCHIVED_HISTORY_TEST_OBSOLETE);\
98  TEST_CASE(name, DIAGNOSTICS_SQLITE_INTEGRITY_COOKIE_TEST);           \
99  TEST_CASE(name, DIAGNOSTICS_SQLITE_INTEGRITY_DATABASE_TRACKER_TEST); \
100  TEST_CASE(name, DIAGNOSTICS_SQLITE_INTEGRITY_HISTORY_TEST);          \
101  TEST_CASE(name, DIAGNOSTICS_SQLITE_INTEGRITY_NSS_CERT_TEST);         \
102  TEST_CASE(name, DIAGNOSTICS_SQLITE_INTEGRITY_NSS_KEY_TEST);          \
103  TEST_CASE(name, DIAGNOSTICS_SQLITE_INTEGRITY_THUMBNAILS_TEST);       \
104  TEST_CASE(name, DIAGNOSTICS_SQLITE_INTEGRITY_WEB_DATA_TEST)
105
106void RecordUMARecoveryResult(DiagnosticsTestId id, RunResultMetrics result) {
107  const std::string name("Diagnostics.Recovery." +
108                         GetTestName(static_cast<DiagnosticsTestId>(id)));
109  switch (id) {
110    TEST_CASES(name);  // See above
111    default:
112      NOTREACHED() << "Unhandled UMA Metric type" << id;
113  }
114}
115
116void RecordUMATestResult(DiagnosticsTestId id, RunResultMetrics result) {
117  const std::string name("Diagnostics.Test." +
118                         GetTestName(static_cast<DiagnosticsTestId>(id)));
119  switch (id) {
120    TEST_CASES(name);  // See above
121    default:
122      NOTREACHED() << "Unhandled UMA Metric type" << id;
123  }
124}
125#undef TEST_CASE
126#undef TEST_CASES
127
128}  // namespace diagnostics
129