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