1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
base / test / launcher / test_results_tracker.h [blame]
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_TEST_LAUNCHER_TEST_RESULTS_TRACKER_H_
#define BASE_TEST_LAUNCHER_TEST_RESULTS_TRACKER_H_
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/test/launcher/test_result.h"
#include "base/threading/thread_checker.h"
namespace base {
class CommandLine;
class FilePath;
// A helper class to output results.
// Note: as currently XML is the only supported format by gtest, we don't
// check output format (e.g. "xml:" prefix) here and output an XML file
// unconditionally.
// Note: we don't output per-test-case or total summary info like
// total failed_test_count, disabled_test_count, elapsed_time and so on.
// Only each test (testcase element in the XML) will have the correct
// failed/disabled/elapsed_time information. Each test won't include
// detailed failure messages either.
class TestResultsTracker {
public:
TestResultsTracker();
TestResultsTracker(const TestResultsTracker&) = delete;
TestResultsTracker& operator=(const TestResultsTracker&) = delete;
~TestResultsTracker();
// Initialize the result tracker. Must be called exactly once before
// calling any other methods. Returns true on success.
[[nodiscard]] bool Init(const CommandLine& command_line);
// Called when a test iteration is starting.
void OnTestIterationStarting();
// Adds |test_name| to the set of discovered tests (this includes all tests
// present in the executable, not necessarily run).
void AddTest(const std::string& test_name);
// Adds |test_name| to the set of disabled tests.
void AddDisabledTest(const std::string& test_name);
// Adds location for the |test_name|. Locations are required for all tests run
// in a given shard, by both the TestLauncher and its delegate.
void AddTestLocation(const std::string& test_name,
const std::string& file,
int line);
// Adds placeholder for the |test_name|. Placeholders are required for all
// tests that are expected to produce results in a given shard.
void AddTestPlaceholder(const std::string& test_name);
// Adds |result| to the stored test results.
void AddTestResult(const TestResult& result);
// Adds to the current iteration the fact that |count| items were leaked by
// one or more tests in |test_names| in its temporary directory.
void AddLeakedItems(int count, const std::vector<std::string>& test_names);
// Even when no iterations have occurred, we still want to generate output
// data with "NOTRUN" status for each test. This method generates a
// placeholder iteration. The first iteration will overwrite the data in the
// placeholder iteration.
void GeneratePlaceholderIteration();
// Prints a summary of current test iteration to stdout.
void PrintSummaryOfCurrentIteration() const;
// Prints a summary of all test iterations (not just the last one) to stdout.
void PrintSummaryOfAllIterations() const;
// Adds a string tag to the JSON summary. This is intended to indicate
// conditions that affect the entire test run, as opposed to individual tests.
void AddGlobalTag(const std::string& tag);
// Saves a JSON summary of all test iterations results to |path|. Adds
// |additional_tags| to the summary (just for this invocation). Returns
// true on success.
[[nodiscard]] bool SaveSummaryAsJSON(
const FilePath& path,
const std::vector<std::string>& additional_tags) const;
// Map where keys are test result statuses, and values are sets of tests
// which finished with that status.
typedef std::map<TestResult::Status, std::set<std::string> > TestStatusMap;
// Returns a test status map (see above) for current test iteration.
TestStatusMap GetTestStatusMapForCurrentIteration() const;
// Returns a test status map (see above) for all test iterations.
TestStatusMap GetTestStatusMapForAllIterations() const;
private:
FRIEND_TEST_ALL_PREFIXES(TestResultsTrackerTest,
SaveSummaryAsJSONWithLinkInResult);
FRIEND_TEST_ALL_PREFIXES(TestResultsTrackerTest,
SaveSummaryAsJSONWithTagInResult);
FRIEND_TEST_ALL_PREFIXES(TestResultsTrackerTest,
SaveSummaryAsJSONWithMultiTagsInResult);
FRIEND_TEST_ALL_PREFIXES(TestResultsTrackerTest,
SaveSummaryAsJSONWithMultiTagsSameNameInResult);
FRIEND_TEST_ALL_PREFIXES(TestResultsTrackerTest,
SaveSummaryAsJSONWithPropertyInResult);
FRIEND_TEST_ALL_PREFIXES(TestResultsTrackerTest,
SaveSummaryAsJSONWithOutTimestampInResult);
FRIEND_TEST_ALL_PREFIXES(TestResultsTrackerTest,
SaveSummaryAsJSONWithTimestampInResult);
void GetTestStatusForIteration(int iteration, TestStatusMap* map) const;
template<typename InputIterator>
void PrintTests(InputIterator first,
InputIterator last,
const std::string& description) const;
void PrintLeaks(int count, const std::vector<std::string>& test_names) const;
struct AggregateTestResult {
AggregateTestResult();
AggregateTestResult(const AggregateTestResult& other);
~AggregateTestResult();
std::vector<TestResult> test_results;
};
struct PerIterationData {
PerIterationData();
PerIterationData(const PerIterationData& other);
~PerIterationData();
// Aggregate test results grouped by full test name.
typedef std::map<std::string, AggregateTestResult> ResultsMap;
ResultsMap results;
// A sequence of tests that leaked files/dirs in their temp directory.
std::vector<std::pair<int, std::vector<std::string>>> leaked_temp_items;
};
struct CodeLocation {
CodeLocation(const std::string& f, int l) : file(f), line(l) {
}
std::string file;
int line;
};
ThreadChecker thread_checker_;
// Print tests that leak files and/or directories in their temp dir.
bool print_temp_leaks_ = false;
// Set of global tags, i.e. strings indicating conditions that apply to
// the entire test run.
std::set<std::string> global_tags_;
// Set of all test names discovered in the current executable.
std::set<std::string> all_tests_;
// CodeLocation for all tests that will be run as a part of this shard.
std::map<std::string, CodeLocation> test_locations_;
// Name of tests that will run and produce results.
std::set<std::string> test_placeholders_;
// Set of all disabled tests in the current executable.
std::set<std::string> disabled_tests_;
// Store test results for each iteration.
std::vector<PerIterationData> per_iteration_data_;
// Index of current iteration (starting from 0). -1 before the first
// iteration.
int iteration_;
// File handle of output file (can be NULL if no file).
raw_ptr<FILE> out_;
};
} // namespace base
#endif // BASE_TEST_LAUNCHER_TEST_RESULTS_TRACKER_H_