| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1 |
// Copyright 2008, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
15 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
16 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
17 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
18 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
19 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
20 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
21 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
22 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
23 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
24 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
25 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
26 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
27 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
28 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
29 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
30 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
31 |
// Google C++ Testing and Mocking Framework (Google Test) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
32 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
33 |
// Sometimes it's desirable to build Google Test by compiling a single file. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
34 |
// This file serves this purpose. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
35 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
36 |
// This line ensures that gtest.h can be compiled on its own, even |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
37 |
// when it's fused. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
38 |
#include "gtest/gtest.h" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
39 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
40 |
// The following lines pull in the real gtest *.cc files. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
41 |
// Copyright 2005, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
42 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
43 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
44 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
45 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
46 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
47 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
48 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
49 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
50 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
51 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
52 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
53 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
54 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
55 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
56 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
57 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
58 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
59 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
60 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
61 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
62 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
63 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
64 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
65 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
66 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
67 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
68 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
69 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
70 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
71 |
// The Google C++ Testing and Mocking Framework (Google Test) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
72 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
73 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
74 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
75 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
76 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
77 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
78 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
79 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
80 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
81 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
82 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
83 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
84 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
85 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
86 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
87 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
88 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
89 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
90 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
91 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
92 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
93 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
94 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
95 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
96 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
97 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
98 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
99 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
100 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
101 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
102 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
103 |
// Utilities for testing Google Test itself and code that uses Google Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
104 |
// (e.g. frameworks built on top of Google Test). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
105 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
106 |
// GOOGLETEST_CM0004 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
107 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
108 |
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
109 |
#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
110 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
111 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
112 |
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
113 |
/* class A needs to have dll-interface to be used by clients of class B */) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
114 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
115 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
116 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
117 |
// This helper class can be used to mock out Google Test failure reporting |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
118 |
// so that we can test Google Test or code that builds on Google Test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
119 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
120 |
// An object of this class appends a TestPartResult object to the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
121 |
// TestPartResultArray object given in the constructor whenever a Google Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
122 |
// failure is reported. It can either intercept only failures that are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
123 |
// generated in the same thread that created this object or it can intercept |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
124 |
// all generated failures. The scope of this mock object can be controlled with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
125 |
// the second argument to the two arguments constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
126 |
class GTEST_API_ ScopedFakeTestPartResultReporter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
127 |
: public TestPartResultReporterInterface { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
128 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
129 |
// The two possible mocking modes of this object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
130 |
enum InterceptMode { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
131 |
INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
132 |
INTERCEPT_ALL_THREADS // Intercepts all failures. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
133 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
134 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
135 |
// The c'tor sets this object as the test part result reporter used |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
136 |
// by Google Test. The 'result' parameter specifies where to report the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
137 |
// results. This reporter will only catch failures generated in the current |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
138 |
// thread. DEPRECATED |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
139 |
explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
140 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
141 |
// Same as above, but you can choose the interception scope of this object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
142 |
ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
143 |
TestPartResultArray* result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
144 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
145 |
// The d'tor restores the previous test part result reporter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
146 |
~ScopedFakeTestPartResultReporter() override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
147 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
148 |
// Appends the TestPartResult object to the TestPartResultArray |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
149 |
// received in the constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
150 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
151 |
// This method is from the TestPartResultReporterInterface |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
152 |
// interface. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
153 |
void ReportTestPartResult(const TestPartResult& result) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
154 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
155 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
156 |
void Init(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
157 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
158 |
const InterceptMode intercept_mode_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
159 |
TestPartResultReporterInterface* old_reporter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
160 |
TestPartResultArray* const result_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
161 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
162 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
163 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
164 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
165 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
166 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
167 |
// A helper class for implementing EXPECT_FATAL_FAILURE() and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
168 |
// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
169 |
// TestPartResultArray contains exactly one failure that has the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
170 |
// type and contains the given substring. If that's not the case, a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
171 |
// non-fatal failure will be generated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
172 |
class GTEST_API_ SingleFailureChecker { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
173 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
174 |
// The constructor remembers the arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
175 |
SingleFailureChecker(const TestPartResultArray* results, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
176 |
TestPartResult::Type type, const std::string& substr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
177 |
~SingleFailureChecker(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
178 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
179 |
const TestPartResultArray* const results_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
180 |
const TestPartResult::Type type_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
181 |
const std::string substr_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
182 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
183 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
184 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
185 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
186 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
187 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
188 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
189 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
190 |
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
191 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
192 |
// A set of macros for testing Google Test assertions or code that's expected |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
193 |
// to generate Google Test fatal failures. It verifies that the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
194 |
// statement will cause exactly one fatal Google Test failure with 'substr' |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
195 |
// being part of the failure message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
196 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
197 |
// There are two different versions of this macro. EXPECT_FATAL_FAILURE only |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
198 |
// affects and considers failures generated in the current thread and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
199 |
// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
200 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
201 |
// The verification of the assertion is done correctly even when the statement |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
202 |
// throws an exception or aborts the current function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
203 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
204 |
// Known restrictions: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
205 |
// - 'statement' cannot reference local non-static variables or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
206 |
// non-static members of the current object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
207 |
// - 'statement' cannot return a value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
208 |
// - You cannot stream a failure message to this macro. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
209 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
210 |
// Note that even though the implementations of the following two |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
211 |
// macros are much alike, we cannot refactor them to use a common |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
212 |
// helper macro, due to some peculiarity in how the preprocessor |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
213 |
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
214 |
// gtest_unittest.cc will fail to compile if we do that. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
215 |
#define EXPECT_FATAL_FAILURE(statement, substr) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
216 |
do { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
217 |
class GTestExpectFatalFailureHelper {\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
218 |
public:\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
219 |
static void Execute() { statement; }\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
220 |
};\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
221 |
::testing::TestPartResultArray gtest_failures;\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
222 |
::testing::internal::SingleFailureChecker gtest_checker(\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
223 |
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
224 |
{\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
225 |
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
226 |
::testing::ScopedFakeTestPartResultReporter:: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
227 |
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
228 |
GTestExpectFatalFailureHelper::Execute();\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
229 |
}\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
230 |
} while (::testing::internal::AlwaysFalse()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
231 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
232 |
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
233 |
do { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
234 |
class GTestExpectFatalFailureHelper {\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
235 |
public:\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
236 |
static void Execute() { statement; }\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
237 |
};\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
238 |
::testing::TestPartResultArray gtest_failures;\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
239 |
::testing::internal::SingleFailureChecker gtest_checker(\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
240 |
>est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
241 |
{\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
242 |
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
243 |
::testing::ScopedFakeTestPartResultReporter:: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
244 |
INTERCEPT_ALL_THREADS, >est_failures);\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
245 |
GTestExpectFatalFailureHelper::Execute();\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
246 |
}\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
247 |
} while (::testing::internal::AlwaysFalse()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
248 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
249 |
// A macro for testing Google Test assertions or code that's expected to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
250 |
// generate Google Test non-fatal failures. It asserts that the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
251 |
// statement will cause exactly one non-fatal Google Test failure with 'substr' |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
252 |
// being part of the failure message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
253 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
254 |
// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
255 |
// affects and considers failures generated in the current thread and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
256 |
// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
257 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
258 |
// 'statement' is allowed to reference local variables and members of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
259 |
// the current object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
260 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
261 |
// The verification of the assertion is done correctly even when the statement |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
262 |
// throws an exception or aborts the current function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
263 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
264 |
// Known restrictions: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
265 |
// - You cannot stream a failure message to this macro. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
266 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
267 |
// Note that even though the implementations of the following two |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
268 |
// macros are much alike, we cannot refactor them to use a common |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
269 |
// helper macro, due to some peculiarity in how the preprocessor |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
270 |
// works. If we do that, the code won't compile when the user gives |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
271 |
// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
272 |
// expands to code containing an unprotected comma. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
273 |
// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
274 |
// catches that. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
275 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
276 |
// For the same reason, we have to write |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
277 |
// if (::testing::internal::AlwaysTrue()) { statement; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
278 |
// instead of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
279 |
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
280 |
// to avoid an MSVC warning on unreachable code. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
281 |
#define EXPECT_NONFATAL_FAILURE(statement, substr) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
282 |
do {\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
283 |
::testing::TestPartResultArray gtest_failures;\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
284 |
::testing::internal::SingleFailureChecker gtest_checker(\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
285 |
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
286 |
(substr));\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
287 |
{\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
288 |
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
289 |
::testing::ScopedFakeTestPartResultReporter:: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
290 |
INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
291 |
if (::testing::internal::AlwaysTrue()) { statement; }\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
292 |
}\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
293 |
} while (::testing::internal::AlwaysFalse()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
294 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
295 |
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
296 |
do {\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
297 |
::testing::TestPartResultArray gtest_failures;\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
298 |
::testing::internal::SingleFailureChecker gtest_checker(\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
299 |
>est_failures, ::testing::TestPartResult::kNonFatalFailure, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
300 |
(substr));\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
301 |
{\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
302 |
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
303 |
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
304 |
>est_failures);\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
305 |
if (::testing::internal::AlwaysTrue()) { statement; }\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
306 |
}\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
307 |
} while (::testing::internal::AlwaysFalse()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
308 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
309 |
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
310 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
311 |
#include <ctype.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
312 |
#include <stdarg.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
313 |
#include <stdio.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
314 |
#include <stdlib.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
315 |
#include <time.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
316 |
#include <wchar.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
317 |
#include <wctype.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
318 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
319 |
#include <algorithm> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
320 |
#include <chrono> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
321 |
#include <cmath> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
322 |
#include <cstdint> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
323 |
#include <iomanip> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
324 |
#include <limits> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
325 |
#include <list> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
326 |
#include <map> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
327 |
#include <ostream> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
328 |
#include <sstream> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
329 |
#include <vector> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
330 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
331 |
#if GTEST_OS_LINUX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
332 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
333 |
# include <fcntl.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
334 |
# include <limits.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
335 |
# include <sched.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
336 |
// Declares vsnprintf(). This header is not available on Windows. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
337 |
# include <strings.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
338 |
# include <sys/mman.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
339 |
# include <sys/time.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
340 |
# include <unistd.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
341 |
# include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
342 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
343 |
#elif GTEST_OS_ZOS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
344 |
# include <sys/time.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
345 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
346 |
// On z/OS we additionally need strings.h for strcasecmp. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
347 |
# include <strings.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
348 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
349 |
#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
350 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
351 |
# include <windows.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
352 |
# undef min |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
353 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
354 |
#elif GTEST_OS_WINDOWS // We are on Windows proper. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
355 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
356 |
# include <windows.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
357 |
# undef min |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
358 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
359 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
360 |
# include <crtdbg.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
361 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
362 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
363 |
# include <io.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
364 |
# include <sys/timeb.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
365 |
# include <sys/types.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
366 |
# include <sys/stat.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
367 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
368 |
# if GTEST_OS_WINDOWS_MINGW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
369 |
# include <sys/time.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
370 |
# endif // GTEST_OS_WINDOWS_MINGW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
371 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
372 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
373 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
374 |
// cpplint thinks that the header is already included, so we want to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
375 |
// silence it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
376 |
# include <sys/time.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
377 |
# include <unistd.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
378 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
379 |
#endif // GTEST_OS_LINUX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
380 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
381 |
#if GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
382 |
# include <stdexcept> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
383 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
384 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
385 |
#if GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
386 |
# include <arpa/inet.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
387 |
# include <netdb.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
388 |
# include <sys/socket.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
389 |
# include <sys/types.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
390 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
391 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
392 |
// Copyright 2005, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
393 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
394 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
395 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
396 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
397 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
398 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
399 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
400 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
401 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
402 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
403 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
404 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
405 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
406 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
407 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
408 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
409 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
410 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
411 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
412 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
413 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
414 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
415 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
416 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
417 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
418 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
419 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
420 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
421 |
// Utility functions and classes used by the Google C++ testing framework.// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
422 |
// This file contains purely Google Test's internal implementation. Please |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
423 |
// DO NOT #INCLUDE IT IN A USER PROGRAM. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
424 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
425 |
#ifndef GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
426 |
#define GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
427 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
428 |
#ifndef _WIN32_WCE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
429 |
# include <errno.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
430 |
#endif // !_WIN32_WCE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
431 |
#include <stddef.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
432 |
#include <stdlib.h> // For strtoll/_strtoul64/malloc/free. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
433 |
#include <string.h> // For memmove. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
434 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
435 |
#include <algorithm> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
436 |
#include <cstdint> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
437 |
#include <memory> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
438 |
#include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
439 |
#include <vector> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
440 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
441 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
442 |
#if GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
443 |
# include <arpa/inet.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
444 |
# include <netdb.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
445 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
446 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
447 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
448 |
# include <windows.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
449 |
#endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
450 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
451 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
452 |
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
453 |
/* class A needs to have dll-interface to be used by clients of class B */) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
454 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
455 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
456 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
457 |
// Declares the flags. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
458 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
459 |
// We don't want the users to modify this flag in the code, but want |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
460 |
// Google Test's own unit tests to be able to access it. Therefore we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
461 |
// declare it here as opposed to in gtest.h. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
462 |
GTEST_DECLARE_bool_(death_test_use_fork); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
463 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
464 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
465 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
466 |
// The value of GetTestTypeId() as seen from within the Google Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
467 |
// library. This is solely for testing GetTestTypeId(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
468 |
GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
469 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
470 |
// Names of the flags (needed for parsing Google Test flags). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
471 |
const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
472 |
const char kBreakOnFailureFlag[] = "break_on_failure"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
473 |
const char kCatchExceptionsFlag[] = "catch_exceptions"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
474 |
const char kColorFlag[] = "color"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
475 |
const char kFailFast[] = "fail_fast"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
476 |
const char kFilterFlag[] = "filter"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
477 |
const char kListTestsFlag[] = "list_tests"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
478 |
const char kOutputFlag[] = "output"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
479 |
const char kBriefFlag[] = "brief"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
480 |
const char kPrintTimeFlag[] = "print_time"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
481 |
const char kPrintUTF8Flag[] = "print_utf8"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
482 |
const char kRandomSeedFlag[] = "random_seed"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
483 |
const char kRepeatFlag[] = "repeat"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
484 |
const char kShuffleFlag[] = "shuffle"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
485 |
const char kStackTraceDepthFlag[] = "stack_trace_depth"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
486 |
const char kStreamResultToFlag[] = "stream_result_to"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
487 |
const char kThrowOnFailureFlag[] = "throw_on_failure"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
488 |
const char kFlagfileFlag[] = "flagfile"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
489 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
490 |
// A valid random seed must be in [1, kMaxRandomSeed]. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
491 |
const int kMaxRandomSeed = 99999; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
492 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
493 |
// g_help_flag is true if and only if the --help flag or an equivalent form |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
494 |
// is specified on the command line. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
495 |
GTEST_API_ extern bool g_help_flag; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
496 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
497 |
// Returns the current time in milliseconds. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
498 |
GTEST_API_ TimeInMillis GetTimeInMillis(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
499 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
500 |
// Returns true if and only if Google Test should use colors in the output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
501 |
GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
502 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
503 |
// Formats the given time in milliseconds as seconds. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
504 |
GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
505 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
506 |
// Converts the given time in milliseconds to a date string in the ISO 8601 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
507 |
// format, without the timezone information. N.B.: due to the use the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
508 |
// non-reentrant localtime() function, this function is not thread safe. Do |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
509 |
// not use it in any code that can be called from multiple threads. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
510 |
GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
511 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
512 |
// Parses a string for an Int32 flag, in the form of "--flag=value". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
513 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
514 |
// On success, stores the value of the flag in *value, and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
515 |
// true. On failure, returns false without changing *value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
516 |
GTEST_API_ bool ParseInt32Flag( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
517 |
const char* str, const char* flag, int32_t* value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
518 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
519 |
// Returns a random seed in range [1, kMaxRandomSeed] based on the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
520 |
// given --gtest_random_seed flag value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
521 |
inline int GetRandomSeedFromFlag(int32_t random_seed_flag) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
522 |
const unsigned int raw_seed = (random_seed_flag == 0) ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
523 |
static_cast<unsigned int>(GetTimeInMillis()) : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
524 |
static_cast<unsigned int>(random_seed_flag); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
525 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
526 |
// Normalizes the actual seed to range [1, kMaxRandomSeed] such that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
527 |
// it's easy to type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
528 |
const int normalized_seed = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
529 |
static_cast<int>((raw_seed - 1U) % |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
530 |
static_cast<unsigned int>(kMaxRandomSeed)) + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
531 |
return normalized_seed; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
532 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
533 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
534 |
// Returns the first valid random seed after 'seed'. The behavior is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
535 |
// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
536 |
// considered to be 1. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
537 |
inline int GetNextRandomSeed(int seed) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
538 |
GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
539 |
<< "Invalid random seed " << seed << " - must be in [1, " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
540 |
<< kMaxRandomSeed << "]."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
541 |
const int next_seed = seed + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
542 |
return (next_seed > kMaxRandomSeed) ? 1 : next_seed; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
543 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
544 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
545 |
// This class saves the values of all Google Test flags in its c'tor, and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
546 |
// restores them in its d'tor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
547 |
class GTestFlagSaver { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
548 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
549 |
// The c'tor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
550 |
GTestFlagSaver() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
551 |
also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
552 |
break_on_failure_ = GTEST_FLAG(break_on_failure); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
553 |
catch_exceptions_ = GTEST_FLAG(catch_exceptions); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
554 |
color_ = GTEST_FLAG(color); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
555 |
death_test_style_ = GTEST_FLAG(death_test_style); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
556 |
death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
557 |
fail_fast_ = GTEST_FLAG(fail_fast); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
558 |
filter_ = GTEST_FLAG(filter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
559 |
internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
560 |
list_tests_ = GTEST_FLAG(list_tests); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
561 |
output_ = GTEST_FLAG(output); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
562 |
brief_ = GTEST_FLAG(brief); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
563 |
print_time_ = GTEST_FLAG(print_time); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
564 |
print_utf8_ = GTEST_FLAG(print_utf8); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
565 |
random_seed_ = GTEST_FLAG(random_seed); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
566 |
repeat_ = GTEST_FLAG(repeat); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
567 |
shuffle_ = GTEST_FLAG(shuffle); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
568 |
stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
569 |
stream_result_to_ = GTEST_FLAG(stream_result_to); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
570 |
throw_on_failure_ = GTEST_FLAG(throw_on_failure); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
571 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
572 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
573 |
// The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
574 |
~GTestFlagSaver() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
575 |
GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
576 |
GTEST_FLAG(break_on_failure) = break_on_failure_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
577 |
GTEST_FLAG(catch_exceptions) = catch_exceptions_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
578 |
GTEST_FLAG(color) = color_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
579 |
GTEST_FLAG(death_test_style) = death_test_style_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
580 |
GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
581 |
GTEST_FLAG(filter) = filter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
582 |
GTEST_FLAG(fail_fast) = fail_fast_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
583 |
GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
584 |
GTEST_FLAG(list_tests) = list_tests_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
585 |
GTEST_FLAG(output) = output_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
586 |
GTEST_FLAG(brief) = brief_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
587 |
GTEST_FLAG(print_time) = print_time_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
588 |
GTEST_FLAG(print_utf8) = print_utf8_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
589 |
GTEST_FLAG(random_seed) = random_seed_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
590 |
GTEST_FLAG(repeat) = repeat_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
591 |
GTEST_FLAG(shuffle) = shuffle_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
592 |
GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
593 |
GTEST_FLAG(stream_result_to) = stream_result_to_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
594 |
GTEST_FLAG(throw_on_failure) = throw_on_failure_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
595 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
596 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
597 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
598 |
// Fields for saving the original values of flags. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
599 |
bool also_run_disabled_tests_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
600 |
bool break_on_failure_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
601 |
bool catch_exceptions_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
602 |
std::string color_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
603 |
std::string death_test_style_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
604 |
bool death_test_use_fork_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
605 |
bool fail_fast_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
606 |
std::string filter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
607 |
std::string internal_run_death_test_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
608 |
bool list_tests_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
609 |
std::string output_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
610 |
bool brief_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
611 |
bool print_time_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
612 |
bool print_utf8_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
613 |
int32_t random_seed_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
614 |
int32_t repeat_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
615 |
bool shuffle_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
616 |
int32_t stack_trace_depth_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
617 |
std::string stream_result_to_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
618 |
bool throw_on_failure_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
619 |
} GTEST_ATTRIBUTE_UNUSED_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
620 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
621 |
// Converts a Unicode code point to a narrow string in UTF-8 encoding. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
622 |
// code_point parameter is of type UInt32 because wchar_t may not be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
623 |
// wide enough to contain a code point. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
624 |
// If the code_point is not a valid Unicode code point |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
625 |
// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
626 |
// to "(Invalid Unicode 0xXXXXXXXX)". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
627 |
GTEST_API_ std::string CodePointToUtf8(uint32_t code_point); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
628 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
629 |
// Converts a wide string to a narrow string in UTF-8 encoding. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
630 |
// The wide string is assumed to have the following encoding: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
631 |
// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
632 |
// UTF-32 if sizeof(wchar_t) == 4 (on Linux) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
633 |
// Parameter str points to a null-terminated wide string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
634 |
// Parameter num_chars may additionally limit the number |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
635 |
// of wchar_t characters processed. -1 is used when the entire string |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
636 |
// should be processed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
637 |
// If the string contains code points that are not valid Unicode code points |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
638 |
// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
639 |
// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
640 |
// and contains invalid UTF-16 surrogate pairs, values in those pairs |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
641 |
// will be encoded as individual Unicode characters from Basic Normal Plane. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
642 |
GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
643 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
644 |
// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
645 |
// if the variable is present. If a file already exists at this location, this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
646 |
// function will write over it. If the variable is present, but the file cannot |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
647 |
// be created, prints an error and exits. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
648 |
void WriteToShardStatusFileIfNeeded(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
649 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
650 |
// Checks whether sharding is enabled by examining the relevant |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
651 |
// environment variable values. If the variables are present, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
652 |
// but inconsistent (e.g., shard_index >= total_shards), prints |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
653 |
// an error and exits. If in_subprocess_for_death_test, sharding is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
654 |
// disabled because it must only be applied to the original test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
655 |
// process. Otherwise, we could filter out death tests we intended to execute. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
656 |
GTEST_API_ bool ShouldShard(const char* total_shards_str, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
657 |
const char* shard_index_str, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
658 |
bool in_subprocess_for_death_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
659 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
660 |
// Parses the environment variable var as a 32-bit integer. If it is unset, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
661 |
// returns default_val. If it is not a 32-bit integer, prints an error and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
662 |
// and aborts. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
663 |
GTEST_API_ int32_t Int32FromEnvOrDie(const char* env_var, int32_t default_val); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
664 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
665 |
// Given the total number of shards, the shard index, and the test id, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
666 |
// returns true if and only if the test should be run on this shard. The test id |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
667 |
// is some arbitrary but unique non-negative integer assigned to each test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
668 |
// method. Assumes that 0 <= shard_index < total_shards. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
669 |
GTEST_API_ bool ShouldRunTestOnShard( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
670 |
int total_shards, int shard_index, int test_id); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
671 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
672 |
// STL container utilities. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
673 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
674 |
// Returns the number of elements in the given container that satisfy |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
675 |
// the given predicate. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
676 |
template <class Container, typename Predicate> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
677 |
inline int CountIf(const Container& c, Predicate predicate) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
678 |
// Implemented as an explicit loop since std::count_if() in libCstd on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
679 |
// Solaris has a non-standard signature. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
680 |
int count = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
681 |
for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
682 |
if (predicate(*it)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
683 |
++count; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
684 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
685 |
return count; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
686 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
687 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
688 |
// Applies a function/functor to each element in the container. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
689 |
template <class Container, typename Functor> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
690 |
void ForEach(const Container& c, Functor functor) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
691 |
std::for_each(c.begin(), c.end(), functor); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
692 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
693 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
694 |
// Returns the i-th element of the vector, or default_value if i is not |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
695 |
// in range [0, v.size()). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
696 |
template <typename E> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
697 |
inline E GetElementOr(const std::vector<E>& v, int i, E default_value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
698 |
return (i < 0 || i >= static_cast<int>(v.size())) ? default_value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
699 |
: v[static_cast<size_t>(i)]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
700 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
701 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
702 |
// Performs an in-place shuffle of a range of the vector's elements. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
703 |
// 'begin' and 'end' are element indices as an STL-style range; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
704 |
// i.e. [begin, end) are shuffled, where 'end' == size() means to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
705 |
// shuffle to the end of the vector. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
706 |
template <typename E> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
707 |
void ShuffleRange(internal::Random* random, int begin, int end, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
708 |
std::vector<E>* v) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
709 |
const int size = static_cast<int>(v->size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
710 |
GTEST_CHECK_(0 <= begin && begin <= size) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
711 |
<< "Invalid shuffle range start " << begin << ": must be in range [0, " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
712 |
<< size << "]."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
713 |
GTEST_CHECK_(begin <= end && end <= size) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
714 |
<< "Invalid shuffle range finish " << end << ": must be in range [" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
715 |
<< begin << ", " << size << "]."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
716 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
717 |
// Fisher-Yates shuffle, from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
718 |
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
719 |
for (int range_width = end - begin; range_width >= 2; range_width--) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
720 |
const int last_in_range = begin + range_width - 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
721 |
const int selected = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
722 |
begin + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
723 |
static_cast<int>(random->Generate(static_cast<uint32_t>(range_width))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
724 |
std::swap((*v)[static_cast<size_t>(selected)], |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
725 |
(*v)[static_cast<size_t>(last_in_range)]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
726 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
727 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
728 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
729 |
// Performs an in-place shuffle of the vector's elements. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
730 |
template <typename E> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
731 |
inline void Shuffle(internal::Random* random, std::vector<E>* v) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
732 |
ShuffleRange(random, 0, static_cast<int>(v->size()), v); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
733 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
734 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
735 |
// A function for deleting an object. Handy for being used as a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
736 |
// functor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
737 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
738 |
static void Delete(T* x) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
739 |
delete x; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
740 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
741 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
742 |
// A predicate that checks the key of a TestProperty against a known key. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
743 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
744 |
// TestPropertyKeyIs is copyable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
745 |
class TestPropertyKeyIs { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
746 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
747 |
// Constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
748 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
749 |
// TestPropertyKeyIs has NO default constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
750 |
explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
751 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
752 |
// Returns true if and only if the test name of test property matches on key_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
753 |
bool operator()(const TestProperty& test_property) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
754 |
return test_property.key() == key_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
755 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
756 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
757 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
758 |
std::string key_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
759 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
760 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
761 |
// Class UnitTestOptions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
762 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
763 |
// This class contains functions for processing options the user |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
764 |
// specifies when running the tests. It has only static members. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
765 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
766 |
// In most cases, the user can specify an option using either an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
767 |
// environment variable or a command line flag. E.g. you can set the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
768 |
// test filter using either GTEST_FILTER or --gtest_filter. If both |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
769 |
// the variable and the flag are present, the latter overrides the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
770 |
// former. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
771 |
class GTEST_API_ UnitTestOptions { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
772 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
773 |
// Functions for processing the gtest_output flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
774 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
775 |
// Returns the output format, or "" for normal printed output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
776 |
static std::string GetOutputFormat(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
777 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
778 |
// Returns the absolute path of the requested output file, or the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
779 |
// default (test_detail.xml in the original working directory) if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
780 |
// none was explicitly specified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
781 |
static std::string GetAbsolutePathToOutputFile(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
782 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
783 |
// Functions for processing the gtest_filter flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
784 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
785 |
// Returns true if and only if the user-specified filter matches the test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
786 |
// suite name and the test name. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
787 |
static bool FilterMatchesTest(const std::string& test_suite_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
788 |
const std::string& test_name); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
789 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
790 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
791 |
// Function for supporting the gtest_catch_exception flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
792 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
793 |
// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
794 |
// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
795 |
// This function is useful as an __except condition. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
796 |
static int GTestShouldProcessSEH(DWORD exception_code); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
797 |
#endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
798 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
799 |
// Returns true if "name" matches the ':' separated list of glob-style |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
800 |
// filters in "filter". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
801 |
static bool MatchesFilter(const std::string& name, const char* filter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
802 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
803 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
804 |
// Returns the current application's name, removing directory path if that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
805 |
// is present. Used by UnitTestOptions::GetOutputFile. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
806 |
GTEST_API_ FilePath GetCurrentExecutableName(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
807 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
808 |
// The role interface for getting the OS stack trace as a string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
809 |
class OsStackTraceGetterInterface { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
810 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
811 |
OsStackTraceGetterInterface() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
812 |
virtual ~OsStackTraceGetterInterface() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
813 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
814 |
// Returns the current OS stack trace as an std::string. Parameters: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
815 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
816 |
// max_depth - the maximum number of stack frames to be included |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
817 |
// in the trace. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
818 |
// skip_count - the number of top frames to be skipped; doesn't count |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
819 |
// against max_depth. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
820 |
virtual std::string CurrentStackTrace(int max_depth, int skip_count) = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
821 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
822 |
// UponLeavingGTest() should be called immediately before Google Test calls |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
823 |
// user code. It saves some information about the current stack that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
824 |
// CurrentStackTrace() will use to find and hide Google Test stack frames. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
825 |
virtual void UponLeavingGTest() = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
826 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
827 |
// This string is inserted in place of stack frames that are part of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
828 |
// Google Test's implementation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
829 |
static const char* const kElidedFramesMarker; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
830 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
831 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
832 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
833 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
834 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
835 |
// A working implementation of the OsStackTraceGetterInterface interface. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
836 |
class OsStackTraceGetter : public OsStackTraceGetterInterface { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
837 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
838 |
OsStackTraceGetter() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
839 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
840 |
std::string CurrentStackTrace(int max_depth, int skip_count) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
841 |
void UponLeavingGTest() override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
842 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
843 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
844 |
#if GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
845 |
Mutex mutex_; // Protects all internal state. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
846 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
847 |
// We save the stack frame below the frame that calls user code. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
848 |
// We do this because the address of the frame immediately below |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
849 |
// the user code changes between the call to UponLeavingGTest() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
850 |
// and any calls to the stack trace code from within the user code. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
851 |
void* caller_frame_ = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
852 |
#endif // GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
853 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
854 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
855 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
856 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
857 |
// Information about a Google Test trace point. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
858 |
struct TraceInfo { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
859 |
const char* file; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
860 |
int line; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
861 |
std::string message; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
862 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
863 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
864 |
// This is the default global test part result reporter used in UnitTestImpl. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
865 |
// This class should only be used by UnitTestImpl. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
866 |
class DefaultGlobalTestPartResultReporter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
867 |
: public TestPartResultReporterInterface { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
868 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
869 |
explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
870 |
// Implements the TestPartResultReporterInterface. Reports the test part |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
871 |
// result in the current test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
872 |
void ReportTestPartResult(const TestPartResult& result) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
873 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
874 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
875 |
UnitTestImpl* const unit_test_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
876 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
877 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
878 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
879 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
880 |
// This is the default per thread test part result reporter used in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
881 |
// UnitTestImpl. This class should only be used by UnitTestImpl. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
882 |
class DefaultPerThreadTestPartResultReporter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
883 |
: public TestPartResultReporterInterface { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
884 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
885 |
explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
886 |
// Implements the TestPartResultReporterInterface. The implementation just |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
887 |
// delegates to the current global test part result reporter of *unit_test_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
888 |
void ReportTestPartResult(const TestPartResult& result) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
889 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
890 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
891 |
UnitTestImpl* const unit_test_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
892 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
893 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
894 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
895 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
896 |
// The private implementation of the UnitTest class. We don't protect |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
897 |
// the methods under a mutex, as this class is not accessible by a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
898 |
// user and the UnitTest class that delegates work to this class does |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
899 |
// proper locking. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
900 |
class GTEST_API_ UnitTestImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
901 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
902 |
explicit UnitTestImpl(UnitTest* parent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
903 |
virtual ~UnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
904 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
905 |
// There are two different ways to register your own TestPartResultReporter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
906 |
// You can register your own repoter to listen either only for test results |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
907 |
// from the current thread or for results from all threads. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
908 |
// By default, each per-thread test result repoter just passes a new |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
909 |
// TestPartResult to the global test result reporter, which registers the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
910 |
// test part result for the currently running test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
911 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
912 |
// Returns the global test part result reporter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
913 |
TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
914 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
915 |
// Sets the global test part result reporter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
916 |
void SetGlobalTestPartResultReporter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
917 |
TestPartResultReporterInterface* reporter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
918 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
919 |
// Returns the test part result reporter for the current thread. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
920 |
TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
921 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
922 |
// Sets the test part result reporter for the current thread. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
923 |
void SetTestPartResultReporterForCurrentThread( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
924 |
TestPartResultReporterInterface* reporter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
925 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
926 |
// Gets the number of successful test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
927 |
int successful_test_suite_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
928 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
929 |
// Gets the number of failed test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
930 |
int failed_test_suite_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
931 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
932 |
// Gets the number of all test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
933 |
int total_test_suite_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
934 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
935 |
// Gets the number of all test suites that contain at least one test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
936 |
// that should run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
937 |
int test_suite_to_run_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
938 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
939 |
// Gets the number of successful tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
940 |
int successful_test_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
941 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
942 |
// Gets the number of skipped tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
943 |
int skipped_test_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
944 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
945 |
// Gets the number of failed tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
946 |
int failed_test_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
947 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
948 |
// Gets the number of disabled tests that will be reported in the XML report. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
949 |
int reportable_disabled_test_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
950 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
951 |
// Gets the number of disabled tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
952 |
int disabled_test_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
953 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
954 |
// Gets the number of tests to be printed in the XML report. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
955 |
int reportable_test_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
956 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
957 |
// Gets the number of all tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
958 |
int total_test_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
959 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
960 |
// Gets the number of tests that should run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
961 |
int test_to_run_count() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
962 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
963 |
// Gets the time of the test program start, in ms from the start of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
964 |
// UNIX epoch. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
965 |
TimeInMillis start_timestamp() const { return start_timestamp_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
966 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
967 |
// Gets the elapsed time, in milliseconds. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
968 |
TimeInMillis elapsed_time() const { return elapsed_time_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
969 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
970 |
// Returns true if and only if the unit test passed (i.e. all test suites |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
971 |
// passed). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
972 |
bool Passed() const { return !Failed(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
973 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
974 |
// Returns true if and only if the unit test failed (i.e. some test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
975 |
// failed or something outside of all tests failed). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
976 |
bool Failed() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
977 |
return failed_test_suite_count() > 0 || ad_hoc_test_result()->Failed(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
978 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
979 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
980 |
// Gets the i-th test suite among all the test suites. i can range from 0 to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
981 |
// total_test_suite_count() - 1. If i is not in that range, returns NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
982 |
const TestSuite* GetTestSuite(int i) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
983 |
const int index = GetElementOr(test_suite_indices_, i, -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
984 |
return index < 0 ? nullptr : test_suites_[static_cast<size_t>(i)]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
985 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
986 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
987 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
988 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
989 |
const TestCase* GetTestCase(int i) const { return GetTestSuite(i); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
990 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
991 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
992 |
// Gets the i-th test suite among all the test suites. i can range from 0 to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
993 |
// total_test_suite_count() - 1. If i is not in that range, returns NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
994 |
TestSuite* GetMutableSuiteCase(int i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
995 |
const int index = GetElementOr(test_suite_indices_, i, -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
996 |
return index < 0 ? nullptr : test_suites_[static_cast<size_t>(index)]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
997 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
998 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
999 |
// Provides access to the event listener list. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1000 |
TestEventListeners* listeners() { return &listeners_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1001 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1002 |
// Returns the TestResult for the test that's currently running, or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1003 |
// the TestResult for the ad hoc test if no test is running. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1004 |
TestResult* current_test_result(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1005 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1006 |
// Returns the TestResult for the ad hoc test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1007 |
const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1008 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1009 |
// Sets the OS stack trace getter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1010 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1011 |
// Does nothing if the input and the current OS stack trace getter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1012 |
// are the same; otherwise, deletes the old getter and makes the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1013 |
// input the current getter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1014 |
void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1015 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1016 |
// Returns the current OS stack trace getter if it is not NULL; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1017 |
// otherwise, creates an OsStackTraceGetter, makes it the current |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1018 |
// getter, and returns it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1019 |
OsStackTraceGetterInterface* os_stack_trace_getter(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1020 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1021 |
// Returns the current OS stack trace as an std::string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1022 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1023 |
// The maximum number of stack frames to be included is specified by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1024 |
// the gtest_stack_trace_depth flag. The skip_count parameter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1025 |
// specifies the number of top frames to be skipped, which doesn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1026 |
// count against the number of frames to be included. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1027 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1028 |
// For example, if Foo() calls Bar(), which in turn calls |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1029 |
// CurrentOsStackTraceExceptTop(1), Foo() will be included in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1030 |
// trace but Bar() and CurrentOsStackTraceExceptTop() won't. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1031 |
std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1032 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1033 |
// Finds and returns a TestSuite with the given name. If one doesn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1034 |
// exist, creates one and returns it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1035 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1036 |
// Arguments: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1037 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1038 |
// test_suite_name: name of the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1039 |
// type_param: the name of the test's type parameter, or NULL if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1040 |
// this is not a typed or a type-parameterized test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1041 |
// set_up_tc: pointer to the function that sets up the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1042 |
// tear_down_tc: pointer to the function that tears down the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1043 |
TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1044 |
internal::SetUpTestSuiteFunc set_up_tc, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1045 |
internal::TearDownTestSuiteFunc tear_down_tc); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1046 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1047 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1048 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1049 |
TestCase* GetTestCase(const char* test_case_name, const char* type_param, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1050 |
internal::SetUpTestSuiteFunc set_up_tc, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1051 |
internal::TearDownTestSuiteFunc tear_down_tc) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1052 |
return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1053 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1054 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1055 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1056 |
// Adds a TestInfo to the unit test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1057 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1058 |
// Arguments: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1059 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1060 |
// set_up_tc: pointer to the function that sets up the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1061 |
// tear_down_tc: pointer to the function that tears down the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1062 |
// test_info: the TestInfo object |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1063 |
void AddTestInfo(internal::SetUpTestSuiteFunc set_up_tc, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1064 |
internal::TearDownTestSuiteFunc tear_down_tc, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1065 |
TestInfo* test_info) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1066 |
#if GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1067 |
// In order to support thread-safe death tests, we need to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1068 |
// remember the original working directory when the test program |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1069 |
// was first invoked. We cannot do this in RUN_ALL_TESTS(), as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1070 |
// the user may have changed the current directory before calling |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1071 |
// RUN_ALL_TESTS(). Therefore we capture the current directory in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1072 |
// AddTestInfo(), which is called to register a TEST or TEST_F |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1073 |
// before main() is reached. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1074 |
if (original_working_dir_.IsEmpty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1075 |
original_working_dir_.Set(FilePath::GetCurrentDir()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1076 |
GTEST_CHECK_(!original_working_dir_.IsEmpty()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1077 |
<< "Failed to get the current working directory."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1078 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1079 |
#endif // GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1080 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1081 |
GetTestSuite(test_info->test_suite_name(), test_info->type_param(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1082 |
set_up_tc, tear_down_tc) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1083 |
->AddTestInfo(test_info); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1084 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1085 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1086 |
// Returns ParameterizedTestSuiteRegistry object used to keep track of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1087 |
// value-parameterized tests and instantiate and register them. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1088 |
internal::ParameterizedTestSuiteRegistry& parameterized_test_registry() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1089 |
return parameterized_test_registry_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1090 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1091 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1092 |
std::set<std::string>* ignored_parameterized_test_suites() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1093 |
return &ignored_parameterized_test_suites_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1094 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1095 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1096 |
// Returns TypeParameterizedTestSuiteRegistry object used to keep track of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1097 |
// type-parameterized tests and instantiations of them. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1098 |
internal::TypeParameterizedTestSuiteRegistry& |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1099 |
type_parameterized_test_registry() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1100 |
return type_parameterized_test_registry_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1101 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1102 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1103 |
// Sets the TestSuite object for the test that's currently running. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1104 |
void set_current_test_suite(TestSuite* a_current_test_suite) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1105 |
current_test_suite_ = a_current_test_suite; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1106 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1107 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1108 |
// Sets the TestInfo object for the test that's currently running. If |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1109 |
// current_test_info is NULL, the assertion results will be stored in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1110 |
// ad_hoc_test_result_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1111 |
void set_current_test_info(TestInfo* a_current_test_info) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1112 |
current_test_info_ = a_current_test_info; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1113 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1114 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1115 |
// Registers all parameterized tests defined using TEST_P and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1116 |
// INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1117 |
// combination. This method can be called more then once; it has guards |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1118 |
// protecting from registering the tests more then once. If |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1119 |
// value-parameterized tests are disabled, RegisterParameterizedTests is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1120 |
// present but does nothing. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1121 |
void RegisterParameterizedTests(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1122 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1123 |
// Runs all tests in this UnitTest object, prints the result, and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1124 |
// returns true if all tests are successful. If any exception is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1125 |
// thrown during a test, this test is considered to be failed, but |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1126 |
// the rest of the tests will still be run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1127 |
bool RunAllTests(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1128 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1129 |
// Clears the results of all tests, except the ad hoc tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1130 |
void ClearNonAdHocTestResult() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1131 |
ForEach(test_suites_, TestSuite::ClearTestSuiteResult); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1132 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1133 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1134 |
// Clears the results of ad-hoc test assertions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1135 |
void ClearAdHocTestResult() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1136 |
ad_hoc_test_result_.Clear(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1137 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1138 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1139 |
// Adds a TestProperty to the current TestResult object when invoked in a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1140 |
// context of a test or a test suite, or to the global property set. If the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1141 |
// result already contains a property with the same key, the value will be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1142 |
// updated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1143 |
void RecordProperty(const TestProperty& test_property); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1144 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1145 |
enum ReactionToSharding { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1146 |
HONOR_SHARDING_PROTOCOL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1147 |
IGNORE_SHARDING_PROTOCOL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1148 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1149 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1150 |
// Matches the full name of each test against the user-specified |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1151 |
// filter to decide whether the test should run, then records the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1152 |
// result in each TestSuite and TestInfo object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1153 |
// If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1154 |
// based on sharding variables in the environment. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1155 |
// Returns the number of tests that should run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1156 |
int FilterTests(ReactionToSharding shard_tests); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1157 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1158 |
// Prints the names of the tests matching the user-specified filter flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1159 |
void ListTestsMatchingFilter(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1160 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1161 |
const TestSuite* current_test_suite() const { return current_test_suite_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1162 |
TestInfo* current_test_info() { return current_test_info_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1163 |
const TestInfo* current_test_info() const { return current_test_info_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1164 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1165 |
// Returns the vector of environments that need to be set-up/torn-down |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1166 |
// before/after the tests are run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1167 |
std::vector<Environment*>& environments() { return environments_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1168 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1169 |
// Getters for the per-thread Google Test trace stack. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1170 |
std::vector<TraceInfo>& gtest_trace_stack() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1171 |
return *(gtest_trace_stack_.pointer()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1172 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1173 |
const std::vector<TraceInfo>& gtest_trace_stack() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1174 |
return gtest_trace_stack_.get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1175 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1176 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1177 |
#if GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1178 |
void InitDeathTestSubprocessControlInfo() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1179 |
internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1180 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1181 |
// Returns a pointer to the parsed --gtest_internal_run_death_test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1182 |
// flag, or NULL if that flag was not specified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1183 |
// This information is useful only in a death test child process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1184 |
// Must not be called before a call to InitGoogleTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1185 |
const InternalRunDeathTestFlag* internal_run_death_test_flag() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1186 |
return internal_run_death_test_flag_.get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1187 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1188 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1189 |
// Returns a pointer to the current death test factory. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1190 |
internal::DeathTestFactory* death_test_factory() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1191 |
return death_test_factory_.get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1192 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1193 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1194 |
void SuppressTestEventsIfInSubprocess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1195 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1196 |
friend class ReplaceDeathTestFactory; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1197 |
#endif // GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1198 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1199 |
// Initializes the event listener performing XML output as specified by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1200 |
// UnitTestOptions. Must not be called before InitGoogleTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1201 |
void ConfigureXmlOutput(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1202 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1203 |
#if GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1204 |
// Initializes the event listener for streaming test results to a socket. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1205 |
// Must not be called before InitGoogleTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1206 |
void ConfigureStreamingOutput(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1207 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1208 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1209 |
// Performs initialization dependent upon flag values obtained in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1210 |
// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1211 |
// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1212 |
// this function is also called from RunAllTests. Since this function can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1213 |
// called more than once, it has to be idempotent. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1214 |
void PostFlagParsingInit(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1215 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1216 |
// Gets the random seed used at the start of the current test iteration. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1217 |
int random_seed() const { return random_seed_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1218 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1219 |
// Gets the random number generator. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1220 |
internal::Random* random() { return &random_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1221 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1222 |
// Shuffles all test suites, and the tests within each test suite, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1223 |
// making sure that death tests are still run first. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1224 |
void ShuffleTests(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1225 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1226 |
// Restores the test suites and tests to their order before the first shuffle. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1227 |
void UnshuffleTests(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1228 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1229 |
// Returns the value of GTEST_FLAG(catch_exceptions) at the moment |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1230 |
// UnitTest::Run() starts. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1231 |
bool catch_exceptions() const { return catch_exceptions_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1232 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1233 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1234 |
friend class ::testing::UnitTest; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1235 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1236 |
// Used by UnitTest::Run() to capture the state of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1237 |
// GTEST_FLAG(catch_exceptions) at the moment it starts. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1238 |
void set_catch_exceptions(bool value) { catch_exceptions_ = value; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1239 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1240 |
// The UnitTest object that owns this implementation object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1241 |
UnitTest* const parent_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1242 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1243 |
// The working directory when the first TEST() or TEST_F() was |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1244 |
// executed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1245 |
internal::FilePath original_working_dir_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1246 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1247 |
// The default test part result reporters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1248 |
DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1249 |
DefaultPerThreadTestPartResultReporter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1250 |
default_per_thread_test_part_result_reporter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1251 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1252 |
// Points to (but doesn't own) the global test part result reporter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1253 |
TestPartResultReporterInterface* global_test_part_result_repoter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1254 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1255 |
// Protects read and write access to global_test_part_result_reporter_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1256 |
internal::Mutex global_test_part_result_reporter_mutex_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1257 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1258 |
// Points to (but doesn't own) the per-thread test part result reporter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1259 |
internal::ThreadLocal<TestPartResultReporterInterface*> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1260 |
per_thread_test_part_result_reporter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1261 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1262 |
// The vector of environments that need to be set-up/torn-down |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1263 |
// before/after the tests are run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1264 |
std::vector<Environment*> environments_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1265 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1266 |
// The vector of TestSuites in their original order. It owns the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1267 |
// elements in the vector. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1268 |
std::vector<TestSuite*> test_suites_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1269 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1270 |
// Provides a level of indirection for the test suite list to allow |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1271 |
// easy shuffling and restoring the test suite order. The i-th |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1272 |
// element of this vector is the index of the i-th test suite in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1273 |
// shuffled order. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1274 |
std::vector<int> test_suite_indices_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1275 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1276 |
// ParameterizedTestRegistry object used to register value-parameterized |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1277 |
// tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1278 |
internal::ParameterizedTestSuiteRegistry parameterized_test_registry_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1279 |
internal::TypeParameterizedTestSuiteRegistry |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1280 |
type_parameterized_test_registry_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1281 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1282 |
// The set holding the name of parameterized |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1283 |
// test suites that may go uninstantiated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1284 |
std::set<std::string> ignored_parameterized_test_suites_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1285 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1286 |
// Indicates whether RegisterParameterizedTests() has been called already. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1287 |
bool parameterized_tests_registered_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1288 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1289 |
// Index of the last death test suite registered. Initially -1. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1290 |
int last_death_test_suite_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1291 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1292 |
// This points to the TestSuite for the currently running test. It |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1293 |
// changes as Google Test goes through one test suite after another. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1294 |
// When no test is running, this is set to NULL and Google Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1295 |
// stores assertion results in ad_hoc_test_result_. Initially NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1296 |
TestSuite* current_test_suite_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1297 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1298 |
// This points to the TestInfo for the currently running test. It |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1299 |
// changes as Google Test goes through one test after another. When |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1300 |
// no test is running, this is set to NULL and Google Test stores |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1301 |
// assertion results in ad_hoc_test_result_. Initially NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1302 |
TestInfo* current_test_info_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1303 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1304 |
// Normally, a user only writes assertions inside a TEST or TEST_F, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1305 |
// or inside a function called by a TEST or TEST_F. Since Google |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1306 |
// Test keeps track of which test is current running, it can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1307 |
// associate such an assertion with the test it belongs to. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1308 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1309 |
// If an assertion is encountered when no TEST or TEST_F is running, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1310 |
// Google Test attributes the assertion result to an imaginary "ad hoc" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1311 |
// test, and records the result in ad_hoc_test_result_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1312 |
TestResult ad_hoc_test_result_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1313 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1314 |
// The list of event listeners that can be used to track events inside |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1315 |
// Google Test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1316 |
TestEventListeners listeners_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1317 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1318 |
// The OS stack trace getter. Will be deleted when the UnitTest |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1319 |
// object is destructed. By default, an OsStackTraceGetter is used, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1320 |
// but the user can set this field to use a custom getter if that is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1321 |
// desired. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1322 |
OsStackTraceGetterInterface* os_stack_trace_getter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1323 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1324 |
// True if and only if PostFlagParsingInit() has been called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1325 |
bool post_flag_parse_init_performed_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1326 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1327 |
// The random number seed used at the beginning of the test run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1328 |
int random_seed_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1329 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1330 |
// Our random number generator. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1331 |
internal::Random random_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1332 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1333 |
// The time of the test program start, in ms from the start of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1334 |
// UNIX epoch. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1335 |
TimeInMillis start_timestamp_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1336 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1337 |
// How long the test took to run, in milliseconds. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1338 |
TimeInMillis elapsed_time_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1339 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1340 |
#if GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1341 |
// The decomposed components of the gtest_internal_run_death_test flag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1342 |
// parsed when RUN_ALL_TESTS is called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1343 |
std::unique_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1344 |
std::unique_ptr<internal::DeathTestFactory> death_test_factory_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1345 |
#endif // GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1346 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1347 |
// A per-thread stack of traces created by the SCOPED_TRACE() macro. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1348 |
internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1349 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1350 |
// The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1351 |
// starts. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1352 |
bool catch_exceptions_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1353 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1354 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1355 |
}; // class UnitTestImpl |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1356 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1357 |
// Convenience function for accessing the global UnitTest |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1358 |
// implementation object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1359 |
inline UnitTestImpl* GetUnitTestImpl() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1360 |
return UnitTest::GetInstance()->impl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1361 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1362 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1363 |
#if GTEST_USES_SIMPLE_RE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1364 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1365 |
// Internal helper functions for implementing the simple regular |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1366 |
// expression matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1367 |
GTEST_API_ bool IsInSet(char ch, const char* str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1368 |
GTEST_API_ bool IsAsciiDigit(char ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1369 |
GTEST_API_ bool IsAsciiPunct(char ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1370 |
GTEST_API_ bool IsRepeat(char ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1371 |
GTEST_API_ bool IsAsciiWhiteSpace(char ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1372 |
GTEST_API_ bool IsAsciiWordChar(char ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1373 |
GTEST_API_ bool IsValidEscape(char ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1374 |
GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1375 |
GTEST_API_ bool ValidateRegex(const char* regex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1376 |
GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1377 |
GTEST_API_ bool MatchRepetitionAndRegexAtHead( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1378 |
bool escaped, char ch, char repeat, const char* regex, const char* str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1379 |
GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1380 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1381 |
#endif // GTEST_USES_SIMPLE_RE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1382 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1383 |
// Parses the command line for Google Test flags, without initializing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1384 |
// other parts of Google Test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1385 |
GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1386 |
GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1387 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1388 |
#if GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1389 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1390 |
// Returns the message describing the last system error, regardless of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1391 |
// platform. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1392 |
GTEST_API_ std::string GetLastErrnoDescription(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1393 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1394 |
// Attempts to parse a string into a positive integer pointed to by the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1395 |
// number parameter. Returns true if that is possible. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1396 |
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1397 |
// it here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1398 |
template <typename Integer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1399 |
bool ParseNaturalNumber(const ::std::string& str, Integer* number) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1400 |
// Fail fast if the given string does not begin with a digit; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1401 |
// this bypasses strtoXXX's "optional leading whitespace and plus |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1402 |
// or minus sign" semantics, which are undesirable here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1403 |
if (str.empty() || !IsDigit(str[0])) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1404 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1405 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1406 |
errno = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1407 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1408 |
char* end; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1409 |
// BiggestConvertible is the largest integer type that system-provided |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1410 |
// string-to-number conversion routines can return. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1411 |
using BiggestConvertible = unsigned long long; // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1412 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1413 |
const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1414 |
const bool parse_success = *end == '\0' && errno == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1415 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1416 |
GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1417 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1418 |
const Integer result = static_cast<Integer>(parsed); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1419 |
if (parse_success && static_cast<BiggestConvertible>(result) == parsed) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1420 |
*number = result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1421 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1422 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1423 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1424 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1425 |
#endif // GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1426 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1427 |
// TestResult contains some private methods that should be hidden from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1428 |
// Google Test user but are required for testing. This class allow our tests |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1429 |
// to access them. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1430 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1431 |
// This class is supplied only for the purpose of testing Google Test's own |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1432 |
// constructs. Do not use it in user tests, either directly or indirectly. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1433 |
class TestResultAccessor { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1434 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1435 |
static void RecordProperty(TestResult* test_result, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1436 |
const std::string& xml_element, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1437 |
const TestProperty& property) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1438 |
test_result->RecordProperty(xml_element, property); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1439 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1440 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1441 |
static void ClearTestPartResults(TestResult* test_result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1442 |
test_result->ClearTestPartResults(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1443 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1444 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1445 |
static const std::vector<testing::TestPartResult>& test_part_results( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1446 |
const TestResult& test_result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1447 |
return test_result.test_part_results(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1448 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1449 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1450 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1451 |
#if GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1452 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1453 |
// Streams test results to the given port on the given host machine. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1454 |
class StreamingListener : public EmptyTestEventListener { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1455 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1456 |
// Abstract base class for writing strings to a socket. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1457 |
class AbstractSocketWriter { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1458 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1459 |
virtual ~AbstractSocketWriter() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1460 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1461 |
// Sends a string to the socket. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1462 |
virtual void Send(const std::string& message) = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1463 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1464 |
// Closes the socket. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1465 |
virtual void CloseConnection() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1466 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1467 |
// Sends a string and a newline to the socket. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1468 |
void SendLn(const std::string& message) { Send(message + "\n"); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1469 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1470 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1471 |
// Concrete class for actually writing strings to a socket. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1472 |
class SocketWriter : public AbstractSocketWriter { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1473 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1474 |
SocketWriter(const std::string& host, const std::string& port) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1475 |
: sockfd_(-1), host_name_(host), port_num_(port) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1476 |
MakeConnection(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1477 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1478 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1479 |
~SocketWriter() override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1480 |
if (sockfd_ != -1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1481 |
CloseConnection(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1482 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1483 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1484 |
// Sends a string to the socket. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1485 |
void Send(const std::string& message) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1486 |
GTEST_CHECK_(sockfd_ != -1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1487 |
<< "Send() can be called only when there is a connection."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1488 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1489 |
const auto len = static_cast<size_t>(message.length()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1490 |
if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1491 |
GTEST_LOG_(WARNING) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1492 |
<< "stream_result_to: failed to stream to " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1493 |
<< host_name_ << ":" << port_num_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1494 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1495 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1496 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1497 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1498 |
// Creates a client socket and connects to the server. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1499 |
void MakeConnection(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1500 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1501 |
// Closes the socket. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1502 |
void CloseConnection() override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1503 |
GTEST_CHECK_(sockfd_ != -1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1504 |
<< "CloseConnection() can be called only when there is a connection."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1505 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1506 |
close(sockfd_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1507 |
sockfd_ = -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1508 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1509 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1510 |
int sockfd_; // socket file descriptor |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1511 |
const std::string host_name_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1512 |
const std::string port_num_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1513 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1514 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1515 |
}; // class SocketWriter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1516 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1517 |
// Escapes '=', '&', '%', and '\n' characters in str as "%xx". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1518 |
static std::string UrlEncode(const char* str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1519 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1520 |
StreamingListener(const std::string& host, const std::string& port) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1521 |
: socket_writer_(new SocketWriter(host, port)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1522 |
Start(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1523 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1524 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1525 |
explicit StreamingListener(AbstractSocketWriter* socket_writer) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1526 |
: socket_writer_(socket_writer) { Start(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1527 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1528 |
void OnTestProgramStart(const UnitTest& /* unit_test */) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1529 |
SendLn("event=TestProgramStart"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1530 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1531 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1532 |
void OnTestProgramEnd(const UnitTest& unit_test) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1533 |
// Note that Google Test current only report elapsed time for each |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1534 |
// test iteration, not for the entire test program. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1535 |
SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1536 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1537 |
// Notify the streaming server to stop. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1538 |
socket_writer_->CloseConnection(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1539 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1540 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1541 |
void OnTestIterationStart(const UnitTest& /* unit_test */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1542 |
int iteration) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1543 |
SendLn("event=TestIterationStart&iteration=" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1544 |
StreamableToString(iteration)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1545 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1546 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1547 |
void OnTestIterationEnd(const UnitTest& unit_test, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1548 |
int /* iteration */) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1549 |
SendLn("event=TestIterationEnd&passed=" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1550 |
FormatBool(unit_test.Passed()) + "&elapsed_time=" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1551 |
StreamableToString(unit_test.elapsed_time()) + "ms"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1552 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1553 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1554 |
// Note that "event=TestCaseStart" is a wire format and has to remain |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1555 |
// "case" for compatibility |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1556 |
void OnTestCaseStart(const TestCase& test_case) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1557 |
SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1558 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1559 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1560 |
// Note that "event=TestCaseEnd" is a wire format and has to remain |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1561 |
// "case" for compatibility |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1562 |
void OnTestCaseEnd(const TestCase& test_case) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1563 |
SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1564 |
"&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1565 |
"ms"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1566 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1567 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1568 |
void OnTestStart(const TestInfo& test_info) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1569 |
SendLn(std::string("event=TestStart&name=") + test_info.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1570 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1571 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1572 |
void OnTestEnd(const TestInfo& test_info) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1573 |
SendLn("event=TestEnd&passed=" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1574 |
FormatBool((test_info.result())->Passed()) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1575 |
"&elapsed_time=" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1576 |
StreamableToString((test_info.result())->elapsed_time()) + "ms"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1577 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1578 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1579 |
void OnTestPartResult(const TestPartResult& test_part_result) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1580 |
const char* file_name = test_part_result.file_name(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1581 |
if (file_name == nullptr) file_name = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1582 |
SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1583 |
"&line=" + StreamableToString(test_part_result.line_number()) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1584 |
"&message=" + UrlEncode(test_part_result.message())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1585 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1586 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1587 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1588 |
// Sends the given message and a newline to the socket. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1589 |
void SendLn(const std::string& message) { socket_writer_->SendLn(message); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1590 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1591 |
// Called at the start of streaming to notify the receiver what |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1592 |
// protocol we are using. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1593 |
void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1594 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1595 |
std::string FormatBool(bool value) { return value ? "1" : "0"; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1596 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1597 |
const std::unique_ptr<AbstractSocketWriter> socket_writer_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1598 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1599 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1600 |
}; // class StreamingListener |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1601 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1602 |
#endif // GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1603 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1604 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1605 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1606 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1607 |
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1608 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1609 |
#endif // GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1610 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1611 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1612 |
# define vsnprintf _vsnprintf |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1613 |
#endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1614 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1615 |
#if GTEST_OS_MAC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1616 |
#ifndef GTEST_OS_IOS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1617 |
#include <crt_externs.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1618 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1619 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1620 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1621 |
#if GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1622 |
#include "absl/debugging/failure_signal_handler.h" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1623 |
#include "absl/debugging/stacktrace.h" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1624 |
#include "absl/debugging/symbolize.h" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1625 |
#include "absl/strings/str_cat.h" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1626 |
#endif // GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1627 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1628 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1629 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1630 |
using internal::CountIf; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1631 |
using internal::ForEach; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1632 |
using internal::GetElementOr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1633 |
using internal::Shuffle; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1634 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1635 |
// Constants. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1636 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1637 |
// A test whose test suite name or test name matches this filter is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1638 |
// disabled and not run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1639 |
static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1640 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1641 |
// A test suite whose name matches this filter is considered a death |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1642 |
// test suite and will be run before test suites whose name doesn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1643 |
// match this filter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1644 |
static const char kDeathTestSuiteFilter[] = "*DeathTest:*DeathTest/*"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1645 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1646 |
// A test filter that matches everything. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1647 |
static const char kUniversalFilter[] = "*"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1648 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1649 |
// The default output format. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1650 |
static const char kDefaultOutputFormat[] = "xml"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1651 |
// The default output file. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1652 |
static const char kDefaultOutputFile[] = "test_detail"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1653 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1654 |
// The environment variable name for the test shard index. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1655 |
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1656 |
// The environment variable name for the total number of test shards. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1657 |
static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1658 |
// The environment variable name for the test shard status file. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1659 |
static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1660 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1661 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1662 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1663 |
// The text used in failure messages to indicate the start of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1664 |
// stack trace. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1665 |
const char kStackTraceMarker[] = "\nStack trace:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1666 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1667 |
// g_help_flag is true if and only if the --help flag or an equivalent form |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1668 |
// is specified on the command line. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1669 |
bool g_help_flag = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1670 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1671 |
// Utilty function to Open File for Writing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1672 |
static FILE* OpenFileForWriting(const std::string& output_file) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1673 |
FILE* fileout = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1674 |
FilePath output_file_path(output_file); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1675 |
FilePath output_dir(output_file_path.RemoveFileName()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1676 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1677 |
if (output_dir.CreateDirectoriesRecursively()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1678 |
fileout = posix::FOpen(output_file.c_str(), "w"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1679 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1680 |
if (fileout == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1681 |
GTEST_LOG_(FATAL) << "Unable to open file \"" << output_file << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1682 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1683 |
return fileout; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1684 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1685 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1686 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1687 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1688 |
// Bazel passes in the argument to '--test_filter' via the TESTBRIDGE_TEST_ONLY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1689 |
// environment variable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1690 |
static const char* GetDefaultFilter() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1691 |
const char* const testbridge_test_only = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1692 |
internal::posix::GetEnv("TESTBRIDGE_TEST_ONLY"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1693 |
if (testbridge_test_only != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1694 |
return testbridge_test_only; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1695 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1696 |
return kUniversalFilter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1697 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1698 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1699 |
// Bazel passes in the argument to '--test_runner_fail_fast' via the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1700 |
// TESTBRIDGE_TEST_RUNNER_FAIL_FAST environment variable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1701 |
static bool GetDefaultFailFast() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1702 |
const char* const testbridge_test_runner_fail_fast = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1703 |
internal::posix::GetEnv("TESTBRIDGE_TEST_RUNNER_FAIL_FAST"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1704 |
if (testbridge_test_runner_fail_fast != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1705 |
return strcmp(testbridge_test_runner_fail_fast, "1") == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1706 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1707 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1708 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1709 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1710 |
GTEST_DEFINE_bool_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1711 |
fail_fast, internal::BoolFromGTestEnv("fail_fast", GetDefaultFailFast()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1712 |
"True if and only if a test failure should stop further test execution."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1713 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1714 |
GTEST_DEFINE_bool_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1715 |
also_run_disabled_tests, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1716 |
internal::BoolFromGTestEnv("also_run_disabled_tests", false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1717 |
"Run disabled tests too, in addition to the tests normally being run."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1718 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1719 |
GTEST_DEFINE_bool_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1720 |
break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1721 |
"True if and only if a failed assertion should be a debugger " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1722 |
"break-point."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1723 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1724 |
GTEST_DEFINE_bool_(catch_exceptions, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1725 |
internal::BoolFromGTestEnv("catch_exceptions", true), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1726 |
"True if and only if " GTEST_NAME_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1727 |
" should catch exceptions and treat them as test failures."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1728 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1729 |
GTEST_DEFINE_string_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1730 |
color, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1731 |
internal::StringFromGTestEnv("color", "auto"), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1732 |
"Whether to use colors in the output. Valid values: yes, no, " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1733 |
"and auto. 'auto' means to use colors if the output is " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1734 |
"being sent to a terminal and the TERM environment variable " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1735 |
"is set to a terminal type that supports colors."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1736 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1737 |
GTEST_DEFINE_string_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1738 |
filter, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1739 |
internal::StringFromGTestEnv("filter", GetDefaultFilter()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1740 |
"A colon-separated list of glob (not regex) patterns " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1741 |
"for filtering the tests to run, optionally followed by a " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1742 |
"'-' and a : separated list of negative patterns (tests to " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1743 |
"exclude). A test is run if it matches one of the positive " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1744 |
"patterns and does not match any of the negative patterns."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1745 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1746 |
GTEST_DEFINE_bool_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1747 |
install_failure_signal_handler, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1748 |
internal::BoolFromGTestEnv("install_failure_signal_handler", false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1749 |
"If true and supported on the current platform, " GTEST_NAME_ " should " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1750 |
"install a signal handler that dumps debugging information when fatal " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1751 |
"signals are raised."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1752 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1753 |
GTEST_DEFINE_bool_(list_tests, false, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1754 |
"List all tests without running them."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1755 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1756 |
// The net priority order after flag processing is thus: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1757 |
// --gtest_output command line flag |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1758 |
// GTEST_OUTPUT environment variable |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1759 |
// XML_OUTPUT_FILE environment variable |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1760 |
// '' |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1761 |
GTEST_DEFINE_string_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1762 |
output, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1763 |
internal::StringFromGTestEnv("output", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1764 |
internal::OutputFlagAlsoCheckEnvVar().c_str()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1765 |
"A format (defaults to \"xml\" but can be specified to be \"json\"), " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1766 |
"optionally followed by a colon and an output file name or directory. " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1767 |
"A directory is indicated by a trailing pathname separator. " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1768 |
"Examples: \"xml:filename.xml\", \"xml::directoryname/\". " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1769 |
"If a directory is specified, output files will be created " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1770 |
"within that directory, with file-names based on the test " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1771 |
"executable's name and, if necessary, made unique by adding " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1772 |
"digits."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1773 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1774 |
GTEST_DEFINE_bool_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1775 |
brief, internal::BoolFromGTestEnv("brief", false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1776 |
"True if only test failures should be displayed in text output."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1777 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1778 |
GTEST_DEFINE_bool_(print_time, internal::BoolFromGTestEnv("print_time", true), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1779 |
"True if and only if " GTEST_NAME_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1780 |
" should display elapsed time in text output."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1781 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1782 |
GTEST_DEFINE_bool_(print_utf8, internal::BoolFromGTestEnv("print_utf8", true), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1783 |
"True if and only if " GTEST_NAME_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1784 |
" prints UTF8 characters as text."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1785 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1786 |
GTEST_DEFINE_int32_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1787 |
random_seed, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1788 |
internal::Int32FromGTestEnv("random_seed", 0), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1789 |
"Random number seed to use when shuffling test orders. Must be in range " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1790 |
"[1, 99999], or 0 to use a seed based on the current time."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1791 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1792 |
GTEST_DEFINE_int32_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1793 |
repeat, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1794 |
internal::Int32FromGTestEnv("repeat", 1), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1795 |
"How many times to repeat each test. Specify a negative number " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1796 |
"for repeating forever. Useful for shaking out flaky tests."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1797 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1798 |
GTEST_DEFINE_bool_(show_internal_stack_frames, false, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1799 |
"True if and only if " GTEST_NAME_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1800 |
" should include internal stack frames when " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1801 |
"printing test failure stack traces."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1802 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1803 |
GTEST_DEFINE_bool_(shuffle, internal::BoolFromGTestEnv("shuffle", false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1804 |
"True if and only if " GTEST_NAME_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1805 |
" should randomize tests' order on every run."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1806 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1807 |
GTEST_DEFINE_int32_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1808 |
stack_trace_depth, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1809 |
internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1810 |
"The maximum number of stack frames to print when an " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1811 |
"assertion fails. The valid range is 0 through 100, inclusive."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1812 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1813 |
GTEST_DEFINE_string_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1814 |
stream_result_to, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1815 |
internal::StringFromGTestEnv("stream_result_to", ""), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1816 |
"This flag specifies the host name and the port number on which to stream " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1817 |
"test results. Example: \"localhost:555\". The flag is effective only on " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1818 |
"Linux."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1819 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1820 |
GTEST_DEFINE_bool_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1821 |
throw_on_failure, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1822 |
internal::BoolFromGTestEnv("throw_on_failure", false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1823 |
"When this flag is specified, a failed assertion will throw an exception " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1824 |
"if exceptions are enabled or exit the program with a non-zero code " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1825 |
"otherwise. For use with an external test framework."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1826 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1827 |
#if GTEST_USE_OWN_FLAGFILE_FLAG_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1828 |
GTEST_DEFINE_string_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1829 |
flagfile, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1830 |
internal::StringFromGTestEnv("flagfile", ""), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1831 |
"This flag specifies the flagfile to read command-line flags from."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1832 |
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1833 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1834 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1835 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1836 |
// Generates a random number from [0, range), using a Linear |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1837 |
// Congruential Generator (LCG). Crashes if 'range' is 0 or greater |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1838 |
// than kMaxRange. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1839 |
uint32_t Random::Generate(uint32_t range) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1840 |
// These constants are the same as are used in glibc's rand(3). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1841 |
// Use wider types than necessary to prevent unsigned overflow diagnostics. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1842 |
state_ = static_cast<uint32_t>(1103515245ULL*state_ + 12345U) % kMaxRange; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1843 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1844 |
GTEST_CHECK_(range > 0) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1845 |
<< "Cannot generate a number in the range [0, 0)."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1846 |
GTEST_CHECK_(range <= kMaxRange) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1847 |
<< "Generation of a number in [0, " << range << ") was requested, " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1848 |
<< "but this can only generate numbers in [0, " << kMaxRange << ")."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1849 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1850 |
// Converting via modulus introduces a bit of downward bias, but |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1851 |
// it's simple, and a linear congruential generator isn't too good |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1852 |
// to begin with. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1853 |
return state_ % range; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1854 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1855 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1856 |
// GTestIsInitialized() returns true if and only if the user has initialized |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1857 |
// Google Test. Useful for catching the user mistake of not initializing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1858 |
// Google Test before calling RUN_ALL_TESTS(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1859 |
static bool GTestIsInitialized() { return GetArgvs().size() > 0; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1860 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1861 |
// Iterates over a vector of TestSuites, keeping a running sum of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1862 |
// results of calling a given int-returning method on each. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1863 |
// Returns the sum. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1864 |
static int SumOverTestSuiteList(const std::vector<TestSuite*>& case_list, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1865 |
int (TestSuite::*method)() const) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1866 |
int sum = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1867 |
for (size_t i = 0; i < case_list.size(); i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1868 |
sum += (case_list[i]->*method)(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1869 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1870 |
return sum; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1871 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1872 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1873 |
// Returns true if and only if the test suite passed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1874 |
static bool TestSuitePassed(const TestSuite* test_suite) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1875 |
return test_suite->should_run() && test_suite->Passed(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1876 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1877 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1878 |
// Returns true if and only if the test suite failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1879 |
static bool TestSuiteFailed(const TestSuite* test_suite) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1880 |
return test_suite->should_run() && test_suite->Failed(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1881 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1882 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1883 |
// Returns true if and only if test_suite contains at least one test that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1884 |
// should run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1885 |
static bool ShouldRunTestSuite(const TestSuite* test_suite) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1886 |
return test_suite->should_run(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1887 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1888 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1889 |
// AssertHelper constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1890 |
AssertHelper::AssertHelper(TestPartResult::Type type, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1891 |
const char* file, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1892 |
int line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1893 |
const char* message) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1894 |
: data_(new AssertHelperData(type, file, line, message)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1895 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1896 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1897 |
AssertHelper::~AssertHelper() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1898 |
delete data_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1899 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1900 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1901 |
// Message assignment, for assertion streaming support. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1902 |
void AssertHelper::operator=(const Message& message) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1903 |
UnitTest::GetInstance()-> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1904 |
AddTestPartResult(data_->type, data_->file, data_->line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1905 |
AppendUserMessage(data_->message, message), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1906 |
UnitTest::GetInstance()->impl() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1907 |
->CurrentOsStackTraceExceptTop(1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1908 |
// Skips the stack frame for this function itself. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1909 |
); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1910 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1911 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1912 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1913 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1914 |
// When TEST_P is found without a matching INSTANTIATE_TEST_SUITE_P |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1915 |
// to creates test cases for it, a syntetic test case is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1916 |
// inserted to report ether an error or a log message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1917 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1918 |
// This configuration bit will likely be removed at some point. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1919 |
constexpr bool kErrorOnUninstantiatedParameterizedTest = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1920 |
constexpr bool kErrorOnUninstantiatedTypeParameterizedTest = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1921 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1922 |
// A test that fails at a given file/line location with a given message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1923 |
class FailureTest : public Test { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1924 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1925 |
explicit FailureTest(const CodeLocation& loc, std::string error_message, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1926 |
bool as_error) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1927 |
: loc_(loc), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1928 |
error_message_(std::move(error_message)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1929 |
as_error_(as_error) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1930 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1931 |
void TestBody() override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1932 |
if (as_error_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1933 |
AssertHelper(TestPartResult::kNonFatalFailure, loc_.file.c_str(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1934 |
loc_.line, "") = Message() << error_message_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1935 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1936 |
std::cout << error_message_ << std::endl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1937 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1938 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1939 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1940 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1941 |
const CodeLocation loc_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1942 |
const std::string error_message_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1943 |
const bool as_error_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1944 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1945 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1946 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1947 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1948 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1949 |
std::set<std::string>* GetIgnoredParameterizedTestSuites() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1950 |
return UnitTest::GetInstance()->impl()->ignored_parameterized_test_suites(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1951 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1952 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1953 |
// Add a given test_suit to the list of them allow to go un-instantiated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1954 |
MarkAsIgnored::MarkAsIgnored(const char* test_suite) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1955 |
GetIgnoredParameterizedTestSuites()->insert(test_suite); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1956 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1957 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1958 |
// If this parameterized test suite has no instantiations (and that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1959 |
// has not been marked as okay), emit a test case reporting that. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1960 |
void InsertSyntheticTestCase(const std::string& name, CodeLocation location, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1961 |
bool has_test_p) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1962 |
const auto& ignored = *GetIgnoredParameterizedTestSuites(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1963 |
if (ignored.find(name) != ignored.end()) return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1964 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1965 |
const char kMissingInstantiation[] = // |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1966 |
" is defined via TEST_P, but never instantiated. None of the test cases " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1967 |
"will run. Either no INSTANTIATE_TEST_SUITE_P is provided or the only " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1968 |
"ones provided expand to nothing." |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1969 |
"\n\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1970 |
"Ideally, TEST_P definitions should only ever be included as part of " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1971 |
"binaries that intend to use them. (As opposed to, for example, being " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1972 |
"placed in a library that may be linked in to get other utilities.)"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1973 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1974 |
const char kMissingTestCase[] = // |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1975 |
" is instantiated via INSTANTIATE_TEST_SUITE_P, but no tests are " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1976 |
"defined via TEST_P . No test cases will run." |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1977 |
"\n\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1978 |
"Ideally, INSTANTIATE_TEST_SUITE_P should only ever be invoked from " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1979 |
"code that always depend on code that provides TEST_P. Failing to do " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1980 |
"so is often an indication of dead code, e.g. the last TEST_P was " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1981 |
"removed but the rest got left behind."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1982 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1983 |
std::string message = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1984 |
"Parameterized test suite " + name + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1985 |
(has_test_p ? kMissingInstantiation : kMissingTestCase) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1986 |
"\n\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1987 |
"To suppress this error for this test suite, insert the following line " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1988 |
"(in a non-header) in the namespace it is defined in:" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1989 |
"\n\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1990 |
"GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" + name + ");"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1991 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1992 |
std::string full_name = "UninstantiatedParameterizedTestSuite<" + name + ">"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1993 |
RegisterTest( // |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1994 |
"GoogleTestVerification", full_name.c_str(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1995 |
nullptr, // No type parameter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1996 |
nullptr, // No value parameter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1997 |
location.file.c_str(), location.line, [message, location] { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1998 |
return new FailureTest(location, message, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1999 |
kErrorOnUninstantiatedParameterizedTest); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2000 |
}); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2001 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2002 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2003 |
void RegisterTypeParameterizedTestSuite(const char* test_suite_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2004 |
CodeLocation code_location) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2005 |
GetUnitTestImpl()->type_parameterized_test_registry().RegisterTestSuite( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2006 |
test_suite_name, code_location); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2007 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2008 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2009 |
void RegisterTypeParameterizedTestSuiteInstantiation(const char* case_name) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2010 |
GetUnitTestImpl() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2011 |
->type_parameterized_test_registry() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2012 |
.RegisterInstantiation(case_name); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2013 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2014 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2015 |
void TypeParameterizedTestSuiteRegistry::RegisterTestSuite( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2016 |
const char* test_suite_name, CodeLocation code_location) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2017 |
suites_.emplace(std::string(test_suite_name), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2018 |
TypeParameterizedTestSuiteInfo(code_location)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2019 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2020 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2021 |
void TypeParameterizedTestSuiteRegistry::RegisterInstantiation( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2022 |
const char* test_suite_name) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2023 |
auto it = suites_.find(std::string(test_suite_name)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2024 |
if (it != suites_.end()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2025 |
it->second.instantiated = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2026 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2027 |
GTEST_LOG_(ERROR) << "Unknown type parameterized test suit '" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2028 |
<< test_suite_name << "'"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2029 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2030 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2031 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2032 |
void TypeParameterizedTestSuiteRegistry::CheckForInstantiations() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2033 |
const auto& ignored = *GetIgnoredParameterizedTestSuites(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2034 |
for (const auto& testcase : suites_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2035 |
if (testcase.second.instantiated) continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2036 |
if (ignored.find(testcase.first) != ignored.end()) continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2037 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2038 |
std::string message = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2039 |
"Type parameterized test suite " + testcase.first + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2040 |
" is defined via REGISTER_TYPED_TEST_SUITE_P, but never instantiated " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2041 |
"via INSTANTIATE_TYPED_TEST_SUITE_P. None of the test cases will run." |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2042 |
"\n\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2043 |
"Ideally, TYPED_TEST_P definitions should only ever be included as " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2044 |
"part of binaries that intend to use them. (As opposed to, for " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2045 |
"example, being placed in a library that may be linked in to get other " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2046 |
"utilities.)" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2047 |
"\n\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2048 |
"To suppress this error for this test suite, insert the following line " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2049 |
"(in a non-header) in the namespace it is defined in:" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2050 |
"\n\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2051 |
"GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2052 |
testcase.first + ");"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2053 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2054 |
std::string full_name = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2055 |
"UninstantiatedTypeParameterizedTestSuite<" + testcase.first + ">"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2056 |
RegisterTest( // |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2057 |
"GoogleTestVerification", full_name.c_str(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2058 |
nullptr, // No type parameter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2059 |
nullptr, // No value parameter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2060 |
testcase.second.code_location.file.c_str(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2061 |
testcase.second.code_location.line, [message, testcase] { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2062 |
return new FailureTest(testcase.second.code_location, message, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2063 |
kErrorOnUninstantiatedTypeParameterizedTest); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2064 |
}); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2065 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2066 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2067 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2068 |
// A copy of all command line arguments. Set by InitGoogleTest(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2069 |
static ::std::vector<std::string> g_argvs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2070 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2071 |
::std::vector<std::string> GetArgvs() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2072 |
#if defined(GTEST_CUSTOM_GET_ARGVS_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2073 |
// GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2074 |
// ::string. This code converts it to the appropriate type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2075 |
const auto& custom = GTEST_CUSTOM_GET_ARGVS_(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2076 |
return ::std::vector<std::string>(custom.begin(), custom.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2077 |
#else // defined(GTEST_CUSTOM_GET_ARGVS_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2078 |
return g_argvs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2079 |
#endif // defined(GTEST_CUSTOM_GET_ARGVS_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2080 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2081 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2082 |
// Returns the current application's name, removing directory path if that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2083 |
// is present. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2084 |
FilePath GetCurrentExecutableName() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2085 |
FilePath result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2086 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2087 |
#if GTEST_OS_WINDOWS || GTEST_OS_OS2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2088 |
result.Set(FilePath(GetArgvs()[0]).RemoveExtension("exe")); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2089 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2090 |
result.Set(FilePath(GetArgvs()[0])); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2091 |
#endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2092 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2093 |
return result.RemoveDirectoryName(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2094 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2095 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2096 |
// Functions for processing the gtest_output flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2097 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2098 |
// Returns the output format, or "" for normal printed output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2099 |
std::string UnitTestOptions::GetOutputFormat() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2100 |
const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2101 |
const char* const colon = strchr(gtest_output_flag, ':'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2102 |
return (colon == nullptr) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2103 |
? std::string(gtest_output_flag) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2104 |
: std::string(gtest_output_flag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2105 |
static_cast<size_t>(colon - gtest_output_flag)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2106 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2107 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2108 |
// Returns the name of the requested output file, or the default if none |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2109 |
// was explicitly specified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2110 |
std::string UnitTestOptions::GetAbsolutePathToOutputFile() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2111 |
const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2112 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2113 |
std::string format = GetOutputFormat(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2114 |
if (format.empty()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2115 |
format = std::string(kDefaultOutputFormat); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2116 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2117 |
const char* const colon = strchr(gtest_output_flag, ':'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2118 |
if (colon == nullptr) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2119 |
return internal::FilePath::MakeFileName( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2120 |
internal::FilePath( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2121 |
UnitTest::GetInstance()->original_working_dir()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2122 |
internal::FilePath(kDefaultOutputFile), 0, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2123 |
format.c_str()).string(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2124 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2125 |
internal::FilePath output_name(colon + 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2126 |
if (!output_name.IsAbsolutePath()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2127 |
output_name = internal::FilePath::ConcatPaths( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2128 |
internal::FilePath(UnitTest::GetInstance()->original_working_dir()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2129 |
internal::FilePath(colon + 1)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2130 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2131 |
if (!output_name.IsDirectory()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2132 |
return output_name.string(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2133 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2134 |
internal::FilePath result(internal::FilePath::GenerateUniqueFileName( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2135 |
output_name, internal::GetCurrentExecutableName(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2136 |
GetOutputFormat().c_str())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2137 |
return result.string(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2138 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2139 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2140 |
// Returns true if and only if the wildcard pattern matches the string. Each |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2141 |
// pattern consists of regular characters, single-character wildcards (?), and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2142 |
// multi-character wildcards (*). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2143 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2144 |
// This function implements a linear-time string globbing algorithm based on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2145 |
// https://research.swtch.com/glob. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2146 |
static bool PatternMatchesString(const std::string& name_str, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2147 |
const char* pattern, const char* pattern_end) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2148 |
const char* name = name_str.c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2149 |
const char* const name_begin = name; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2150 |
const char* const name_end = name + name_str.size(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2151 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2152 |
const char* pattern_next = pattern; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2153 |
const char* name_next = name; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2154 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2155 |
while (pattern < pattern_end || name < name_end) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2156 |
if (pattern < pattern_end) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2157 |
switch (*pattern) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2158 |
default: // Match an ordinary character. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2159 |
if (name < name_end && *name == *pattern) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2160 |
++pattern; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2161 |
++name; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2162 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2163 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2164 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2165 |
case '?': // Match any single character. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2166 |
if (name < name_end) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2167 |
++pattern; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2168 |
++name; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2169 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2170 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2171 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2172 |
case '*': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2173 |
// Match zero or more characters. Start by skipping over the wildcard |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2174 |
// and matching zero characters from name. If that fails, restart and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2175 |
// match one more character than the last attempt. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2176 |
pattern_next = pattern; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2177 |
name_next = name + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2178 |
++pattern; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2179 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2180 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2181 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2182 |
// Failed to match a character. Restart if possible. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2183 |
if (name_begin < name_next && name_next <= name_end) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2184 |
pattern = pattern_next; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2185 |
name = name_next; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2186 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2187 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2188 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2189 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2190 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2191 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2192 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2193 |
bool UnitTestOptions::MatchesFilter(const std::string& name_str, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2194 |
const char* filter) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2195 |
// The filter is a list of patterns separated by colons (:). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2196 |
const char* pattern = filter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2197 |
while (true) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2198 |
// Find the bounds of this pattern. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2199 |
const char* const next_sep = strchr(pattern, ':'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2200 |
const char* const pattern_end = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2201 |
next_sep != nullptr ? next_sep : pattern + strlen(pattern); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2202 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2203 |
// Check if this pattern matches name_str. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2204 |
if (PatternMatchesString(name_str, pattern, pattern_end)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2205 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2206 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2207 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2208 |
// Give up on this pattern. However, if we found a pattern separator (:), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2209 |
// advance to the next pattern (skipping over the separator) and restart. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2210 |
if (next_sep == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2211 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2212 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2213 |
pattern = next_sep + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2214 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2215 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2216 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2217 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2218 |
// Returns true if and only if the user-specified filter matches the test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2219 |
// suite name and the test name. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2220 |
bool UnitTestOptions::FilterMatchesTest(const std::string& test_suite_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2221 |
const std::string& test_name) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2222 |
const std::string& full_name = test_suite_name + "." + test_name.c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2223 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2224 |
// Split --gtest_filter at '-', if there is one, to separate into |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2225 |
// positive filter and negative filter portions |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2226 |
const char* const p = GTEST_FLAG(filter).c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2227 |
const char* const dash = strchr(p, '-'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2228 |
std::string positive; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2229 |
std::string negative; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2230 |
if (dash == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2231 |
positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2232 |
negative = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2233 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2234 |
positive = std::string(p, dash); // Everything up to the dash |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2235 |
negative = std::string(dash + 1); // Everything after the dash |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2236 |
if (positive.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2237 |
// Treat '-test1' as the same as '*-test1' |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2238 |
positive = kUniversalFilter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2239 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2240 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2241 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2242 |
// A filter is a colon-separated list of patterns. It matches a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2243 |
// test if any pattern in it matches the test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2244 |
return (MatchesFilter(full_name, positive.c_str()) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2245 |
!MatchesFilter(full_name, negative.c_str())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2246 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2247 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2248 |
#if GTEST_HAS_SEH |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2249 |
// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2250 |
// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2251 |
// This function is useful as an __except condition. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2252 |
int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2253 |
// Google Test should handle a SEH exception if: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2254 |
// 1. the user wants it to, AND |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2255 |
// 2. this is not a breakpoint exception, AND |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2256 |
// 3. this is not a C++ exception (VC++ implements them via SEH, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2257 |
// apparently). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2258 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2259 |
// SEH exception code for C++ exceptions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2260 |
// (see http://support.microsoft.com/kb/185294 for more information). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2261 |
const DWORD kCxxExceptionCode = 0xe06d7363; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2262 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2263 |
bool should_handle = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2264 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2265 |
if (!GTEST_FLAG(catch_exceptions)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2266 |
should_handle = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2267 |
else if (exception_code == EXCEPTION_BREAKPOINT) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2268 |
should_handle = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2269 |
else if (exception_code == kCxxExceptionCode) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2270 |
should_handle = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2271 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2272 |
return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2273 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2274 |
#endif // GTEST_HAS_SEH |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2275 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2276 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2277 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2278 |
// The c'tor sets this object as the test part result reporter used by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2279 |
// Google Test. The 'result' parameter specifies where to report the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2280 |
// results. Intercepts only failures from the current thread. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2281 |
ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2282 |
TestPartResultArray* result) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2283 |
: intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2284 |
result_(result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2285 |
Init(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2286 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2287 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2288 |
// The c'tor sets this object as the test part result reporter used by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2289 |
// Google Test. The 'result' parameter specifies where to report the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2290 |
// results. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2291 |
ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2292 |
InterceptMode intercept_mode, TestPartResultArray* result) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2293 |
: intercept_mode_(intercept_mode), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2294 |
result_(result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2295 |
Init(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2296 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2297 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2298 |
void ScopedFakeTestPartResultReporter::Init() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2299 |
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2300 |
if (intercept_mode_ == INTERCEPT_ALL_THREADS) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2301 |
old_reporter_ = impl->GetGlobalTestPartResultReporter(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2302 |
impl->SetGlobalTestPartResultReporter(this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2303 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2304 |
old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2305 |
impl->SetTestPartResultReporterForCurrentThread(this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2306 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2307 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2308 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2309 |
// The d'tor restores the test part result reporter used by Google Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2310 |
// before. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2311 |
ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2312 |
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2313 |
if (intercept_mode_ == INTERCEPT_ALL_THREADS) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2314 |
impl->SetGlobalTestPartResultReporter(old_reporter_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2315 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2316 |
impl->SetTestPartResultReporterForCurrentThread(old_reporter_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2317 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2318 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2319 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2320 |
// Increments the test part result count and remembers the result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2321 |
// This method is from the TestPartResultReporterInterface interface. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2322 |
void ScopedFakeTestPartResultReporter::ReportTestPartResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2323 |
const TestPartResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2324 |
result_->Append(result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2325 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2326 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2327 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2328 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2329 |
// Returns the type ID of ::testing::Test. We should always call this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2330 |
// instead of GetTypeId< ::testing::Test>() to get the type ID of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2331 |
// testing::Test. This is to work around a suspected linker bug when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2332 |
// using Google Test as a framework on Mac OS X. The bug causes |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2333 |
// GetTypeId< ::testing::Test>() to return different values depending |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2334 |
// on whether the call is from the Google Test framework itself or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2335 |
// from user test code. GetTestTypeId() is guaranteed to always |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2336 |
// return the same value, as it always calls GetTypeId<>() from the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2337 |
// gtest.cc, which is within the Google Test framework. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2338 |
TypeId GetTestTypeId() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2339 |
return GetTypeId<Test>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2340 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2341 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2342 |
// The value of GetTestTypeId() as seen from within the Google Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2343 |
// library. This is solely for testing GetTestTypeId(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2344 |
extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2345 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2346 |
// This predicate-formatter checks that 'results' contains a test part |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2347 |
// failure of the given type and that the failure message contains the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2348 |
// given substring. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2349 |
static AssertionResult HasOneFailure(const char* /* results_expr */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2350 |
const char* /* type_expr */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2351 |
const char* /* substr_expr */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2352 |
const TestPartResultArray& results, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2353 |
TestPartResult::Type type, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2354 |
const std::string& substr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2355 |
const std::string expected(type == TestPartResult::kFatalFailure ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2356 |
"1 fatal failure" : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2357 |
"1 non-fatal failure"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2358 |
Message msg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2359 |
if (results.size() != 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2360 |
msg << "Expected: " << expected << "\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2361 |
<< " Actual: " << results.size() << " failures"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2362 |
for (int i = 0; i < results.size(); i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2363 |
msg << "\n" << results.GetTestPartResult(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2364 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2365 |
return AssertionFailure() << msg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2366 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2367 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2368 |
const TestPartResult& r = results.GetTestPartResult(0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2369 |
if (r.type() != type) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2370 |
return AssertionFailure() << "Expected: " << expected << "\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2371 |
<< " Actual:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2372 |
<< r; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2373 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2374 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2375 |
if (strstr(r.message(), substr.c_str()) == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2376 |
return AssertionFailure() << "Expected: " << expected << " containing \"" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2377 |
<< substr << "\"\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2378 |
<< " Actual:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2379 |
<< r; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2380 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2381 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2382 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2383 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2384 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2385 |
// The constructor of SingleFailureChecker remembers where to look up |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2386 |
// test part results, what type of failure we expect, and what |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2387 |
// substring the failure message should contain. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2388 |
SingleFailureChecker::SingleFailureChecker(const TestPartResultArray* results, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2389 |
TestPartResult::Type type, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2390 |
const std::string& substr) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2391 |
: results_(results), type_(type), substr_(substr) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2392 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2393 |
// The destructor of SingleFailureChecker verifies that the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2394 |
// TestPartResultArray contains exactly one failure that has the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2395 |
// type and contains the given substring. If that's not the case, a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2396 |
// non-fatal failure will be generated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2397 |
SingleFailureChecker::~SingleFailureChecker() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2398 |
EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2399 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2400 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2401 |
DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2402 |
UnitTestImpl* unit_test) : unit_test_(unit_test) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2403 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2404 |
void DefaultGlobalTestPartResultReporter::ReportTestPartResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2405 |
const TestPartResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2406 |
unit_test_->current_test_result()->AddTestPartResult(result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2407 |
unit_test_->listeners()->repeater()->OnTestPartResult(result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2408 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2409 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2410 |
DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2411 |
UnitTestImpl* unit_test) : unit_test_(unit_test) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2412 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2413 |
void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2414 |
const TestPartResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2415 |
unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2416 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2417 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2418 |
// Returns the global test part result reporter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2419 |
TestPartResultReporterInterface* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2420 |
UnitTestImpl::GetGlobalTestPartResultReporter() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2421 |
internal::MutexLock lock(&global_test_part_result_reporter_mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2422 |
return global_test_part_result_repoter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2423 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2424 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2425 |
// Sets the global test part result reporter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2426 |
void UnitTestImpl::SetGlobalTestPartResultReporter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2427 |
TestPartResultReporterInterface* reporter) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2428 |
internal::MutexLock lock(&global_test_part_result_reporter_mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2429 |
global_test_part_result_repoter_ = reporter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2430 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2431 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2432 |
// Returns the test part result reporter for the current thread. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2433 |
TestPartResultReporterInterface* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2434 |
UnitTestImpl::GetTestPartResultReporterForCurrentThread() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2435 |
return per_thread_test_part_result_reporter_.get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2436 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2437 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2438 |
// Sets the test part result reporter for the current thread. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2439 |
void UnitTestImpl::SetTestPartResultReporterForCurrentThread( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2440 |
TestPartResultReporterInterface* reporter) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2441 |
per_thread_test_part_result_reporter_.set(reporter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2442 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2443 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2444 |
// Gets the number of successful test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2445 |
int UnitTestImpl::successful_test_suite_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2446 |
return CountIf(test_suites_, TestSuitePassed); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2447 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2448 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2449 |
// Gets the number of failed test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2450 |
int UnitTestImpl::failed_test_suite_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2451 |
return CountIf(test_suites_, TestSuiteFailed); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2452 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2453 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2454 |
// Gets the number of all test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2455 |
int UnitTestImpl::total_test_suite_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2456 |
return static_cast<int>(test_suites_.size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2457 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2458 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2459 |
// Gets the number of all test suites that contain at least one test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2460 |
// that should run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2461 |
int UnitTestImpl::test_suite_to_run_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2462 |
return CountIf(test_suites_, ShouldRunTestSuite); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2463 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2464 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2465 |
// Gets the number of successful tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2466 |
int UnitTestImpl::successful_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2467 |
return SumOverTestSuiteList(test_suites_, &TestSuite::successful_test_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2468 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2469 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2470 |
// Gets the number of skipped tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2471 |
int UnitTestImpl::skipped_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2472 |
return SumOverTestSuiteList(test_suites_, &TestSuite::skipped_test_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2473 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2474 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2475 |
// Gets the number of failed tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2476 |
int UnitTestImpl::failed_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2477 |
return SumOverTestSuiteList(test_suites_, &TestSuite::failed_test_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2478 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2479 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2480 |
// Gets the number of disabled tests that will be reported in the XML report. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2481 |
int UnitTestImpl::reportable_disabled_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2482 |
return SumOverTestSuiteList(test_suites_, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2483 |
&TestSuite::reportable_disabled_test_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2484 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2485 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2486 |
// Gets the number of disabled tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2487 |
int UnitTestImpl::disabled_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2488 |
return SumOverTestSuiteList(test_suites_, &TestSuite::disabled_test_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2489 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2490 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2491 |
// Gets the number of tests to be printed in the XML report. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2492 |
int UnitTestImpl::reportable_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2493 |
return SumOverTestSuiteList(test_suites_, &TestSuite::reportable_test_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2494 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2495 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2496 |
// Gets the number of all tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2497 |
int UnitTestImpl::total_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2498 |
return SumOverTestSuiteList(test_suites_, &TestSuite::total_test_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2499 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2500 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2501 |
// Gets the number of tests that should run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2502 |
int UnitTestImpl::test_to_run_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2503 |
return SumOverTestSuiteList(test_suites_, &TestSuite::test_to_run_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2504 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2505 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2506 |
// Returns the current OS stack trace as an std::string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2507 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2508 |
// The maximum number of stack frames to be included is specified by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2509 |
// the gtest_stack_trace_depth flag. The skip_count parameter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2510 |
// specifies the number of top frames to be skipped, which doesn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2511 |
// count against the number of frames to be included. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2512 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2513 |
// For example, if Foo() calls Bar(), which in turn calls |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2514 |
// CurrentOsStackTraceExceptTop(1), Foo() will be included in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2515 |
// trace but Bar() and CurrentOsStackTraceExceptTop() won't. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2516 |
std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2517 |
return os_stack_trace_getter()->CurrentStackTrace( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2518 |
static_cast<int>(GTEST_FLAG(stack_trace_depth)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2519 |
skip_count + 1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2520 |
// Skips the user-specified number of frames plus this function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2521 |
// itself. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2522 |
); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2523 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2524 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2525 |
// A helper class for measuring elapsed times. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2526 |
class Timer { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2527 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2528 |
Timer() : start_(std::chrono::steady_clock::now()) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2529 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2530 |
// Return time elapsed in milliseconds since the timer was created. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2531 |
TimeInMillis Elapsed() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2532 |
return std::chrono::duration_cast<std::chrono::milliseconds>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2533 |
std::chrono::steady_clock::now() - start_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2534 |
.count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2535 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2536 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2537 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2538 |
std::chrono::steady_clock::time_point start_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2539 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2540 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2541 |
// Returns a timestamp as milliseconds since the epoch. Note this time may jump |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2542 |
// around subject to adjustments by the system, to measure elapsed time use |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2543 |
// Timer instead. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2544 |
TimeInMillis GetTimeInMillis() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2545 |
return std::chrono::duration_cast<std::chrono::milliseconds>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2546 |
std::chrono::system_clock::now() - |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2547 |
std::chrono::system_clock::from_time_t(0)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2548 |
.count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2549 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2550 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2551 |
// Utilities |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2552 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2553 |
// class String. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2554 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2555 |
#if GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2556 |
// Creates a UTF-16 wide string from the given ANSI string, allocating |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2557 |
// memory using new. The caller is responsible for deleting the return |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2558 |
// value using delete[]. Returns the wide string, or NULL if the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2559 |
// input is NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2560 |
LPCWSTR String::AnsiToUtf16(const char* ansi) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2561 |
if (!ansi) return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2562 |
const int length = strlen(ansi); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2563 |
const int unicode_length = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2564 |
MultiByteToWideChar(CP_ACP, 0, ansi, length, nullptr, 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2565 |
WCHAR* unicode = new WCHAR[unicode_length + 1]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2566 |
MultiByteToWideChar(CP_ACP, 0, ansi, length, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2567 |
unicode, unicode_length); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2568 |
unicode[unicode_length] = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2569 |
return unicode; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2570 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2571 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2572 |
// Creates an ANSI string from the given wide string, allocating |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2573 |
// memory using new. The caller is responsible for deleting the return |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2574 |
// value using delete[]. Returns the ANSI string, or NULL if the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2575 |
// input is NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2576 |
const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2577 |
if (!utf16_str) return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2578 |
const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, nullptr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2579 |
0, nullptr, nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2580 |
char* ansi = new char[ansi_length + 1]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2581 |
WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, nullptr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2582 |
nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2583 |
ansi[ansi_length] = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2584 |
return ansi; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2585 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2586 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2587 |
#endif // GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2588 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2589 |
// Compares two C strings. Returns true if and only if they have the same |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2590 |
// content. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2591 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2592 |
// Unlike strcmp(), this function can handle NULL argument(s). A NULL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2593 |
// C string is considered different to any non-NULL C string, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2594 |
// including the empty string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2595 |
bool String::CStringEquals(const char * lhs, const char * rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2596 |
if (lhs == nullptr) return rhs == nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2597 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2598 |
if (rhs == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2599 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2600 |
return strcmp(lhs, rhs) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2601 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2602 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2603 |
#if GTEST_HAS_STD_WSTRING |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2604 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2605 |
// Converts an array of wide chars to a narrow string using the UTF-8 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2606 |
// encoding, and streams the result to the given Message object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2607 |
static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2608 |
Message* msg) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2609 |
for (size_t i = 0; i != length; ) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2610 |
if (wstr[i] != L'\0') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2611 |
*msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2612 |
while (i != length && wstr[i] != L'\0') |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2613 |
i++; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2614 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2615 |
*msg << '\0'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2616 |
i++; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2617 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2618 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2619 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2620 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2621 |
#endif // GTEST_HAS_STD_WSTRING |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2622 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2623 |
void SplitString(const ::std::string& str, char delimiter, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2624 |
::std::vector< ::std::string>* dest) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2625 |
::std::vector< ::std::string> parsed; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2626 |
::std::string::size_type pos = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2627 |
while (::testing::internal::AlwaysTrue()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2628 |
const ::std::string::size_type colon = str.find(delimiter, pos); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2629 |
if (colon == ::std::string::npos) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2630 |
parsed.push_back(str.substr(pos)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2631 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2632 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2633 |
parsed.push_back(str.substr(pos, colon - pos)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2634 |
pos = colon + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2635 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2636 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2637 |
dest->swap(parsed); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2638 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2639 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2640 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2641 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2642 |
// Constructs an empty Message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2643 |
// We allocate the stringstream separately because otherwise each use of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2644 |
// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2645 |
// stack frame leading to huge stack frames in some cases; gcc does not reuse |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2646 |
// the stack space. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2647 |
Message::Message() : ss_(new ::std::stringstream) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2648 |
// By default, we want there to be enough precision when printing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2649 |
// a double to a Message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2650 |
*ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2651 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2652 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2653 |
// These two overloads allow streaming a wide C string to a Message |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2654 |
// using the UTF-8 encoding. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2655 |
Message& Message::operator <<(const wchar_t* wide_c_str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2656 |
return *this << internal::String::ShowWideCString(wide_c_str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2657 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2658 |
Message& Message::operator <<(wchar_t* wide_c_str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2659 |
return *this << internal::String::ShowWideCString(wide_c_str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2660 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2661 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2662 |
#if GTEST_HAS_STD_WSTRING |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2663 |
// Converts the given wide string to a narrow string using the UTF-8 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2664 |
// encoding, and streams the result to this Message object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2665 |
Message& Message::operator <<(const ::std::wstring& wstr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2666 |
internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2667 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2668 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2669 |
#endif // GTEST_HAS_STD_WSTRING |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2670 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2671 |
// Gets the text streamed to this object so far as an std::string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2672 |
// Each '\0' character in the buffer is replaced with "\\0". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2673 |
std::string Message::GetString() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2674 |
return internal::StringStreamToString(ss_.get()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2675 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2676 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2677 |
// AssertionResult constructors. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2678 |
// Used in EXPECT_TRUE/FALSE(assertion_result). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2679 |
AssertionResult::AssertionResult(const AssertionResult& other) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2680 |
: success_(other.success_), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2681 |
message_(other.message_.get() != nullptr |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2682 |
? new ::std::string(*other.message_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2683 |
: static_cast< ::std::string*>(nullptr)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2684 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2685 |
// Swaps two AssertionResults. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2686 |
void AssertionResult::swap(AssertionResult& other) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2687 |
using std::swap; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2688 |
swap(success_, other.success_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2689 |
swap(message_, other.message_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2690 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2691 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2692 |
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2693 |
AssertionResult AssertionResult::operator!() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2694 |
AssertionResult negation(!success_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2695 |
if (message_.get() != nullptr) negation << *message_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2696 |
return negation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2697 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2698 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2699 |
// Makes a successful assertion result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2700 |
AssertionResult AssertionSuccess() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2701 |
return AssertionResult(true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2702 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2703 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2704 |
// Makes a failed assertion result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2705 |
AssertionResult AssertionFailure() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2706 |
return AssertionResult(false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2707 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2708 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2709 |
// Makes a failed assertion result with the given failure message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2710 |
// Deprecated; use AssertionFailure() << message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2711 |
AssertionResult AssertionFailure(const Message& message) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2712 |
return AssertionFailure() << message; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2713 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2714 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2715 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2716 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2717 |
namespace edit_distance { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2718 |
std::vector<EditType> CalculateOptimalEdits(const std::vector<size_t>& left, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2719 |
const std::vector<size_t>& right) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2720 |
std::vector<std::vector<double> > costs( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2721 |
left.size() + 1, std::vector<double>(right.size() + 1)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2722 |
std::vector<std::vector<EditType> > best_move( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2723 |
left.size() + 1, std::vector<EditType>(right.size() + 1)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2724 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2725 |
// Populate for empty right. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2726 |
for (size_t l_i = 0; l_i < costs.size(); ++l_i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2727 |
costs[l_i][0] = static_cast<double>(l_i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2728 |
best_move[l_i][0] = kRemove; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2729 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2730 |
// Populate for empty left. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2731 |
for (size_t r_i = 1; r_i < costs[0].size(); ++r_i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2732 |
costs[0][r_i] = static_cast<double>(r_i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2733 |
best_move[0][r_i] = kAdd; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2734 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2735 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2736 |
for (size_t l_i = 0; l_i < left.size(); ++l_i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2737 |
for (size_t r_i = 0; r_i < right.size(); ++r_i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2738 |
if (left[l_i] == right[r_i]) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2739 |
// Found a match. Consume it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2740 |
costs[l_i + 1][r_i + 1] = costs[l_i][r_i]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2741 |
best_move[l_i + 1][r_i + 1] = kMatch; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2742 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2743 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2744 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2745 |
const double add = costs[l_i + 1][r_i]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2746 |
const double remove = costs[l_i][r_i + 1]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2747 |
const double replace = costs[l_i][r_i]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2748 |
if (add < remove && add < replace) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2749 |
costs[l_i + 1][r_i + 1] = add + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2750 |
best_move[l_i + 1][r_i + 1] = kAdd; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2751 |
} else if (remove < add && remove < replace) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2752 |
costs[l_i + 1][r_i + 1] = remove + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2753 |
best_move[l_i + 1][r_i + 1] = kRemove; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2754 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2755 |
// We make replace a little more expensive than add/remove to lower |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2756 |
// their priority. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2757 |
costs[l_i + 1][r_i + 1] = replace + 1.00001; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2758 |
best_move[l_i + 1][r_i + 1] = kReplace; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2759 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2760 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2761 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2762 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2763 |
// Reconstruct the best path. We do it in reverse order. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2764 |
std::vector<EditType> best_path; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2765 |
for (size_t l_i = left.size(), r_i = right.size(); l_i > 0 || r_i > 0;) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2766 |
EditType move = best_move[l_i][r_i]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2767 |
best_path.push_back(move); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2768 |
l_i -= move != kAdd; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2769 |
r_i -= move != kRemove; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2770 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2771 |
std::reverse(best_path.begin(), best_path.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2772 |
return best_path; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2773 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2774 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2775 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2776 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2777 |
// Helper class to convert string into ids with deduplication. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2778 |
class InternalStrings { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2779 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2780 |
size_t GetId(const std::string& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2781 |
IdMap::iterator it = ids_.find(str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2782 |
if (it != ids_.end()) return it->second; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2783 |
size_t id = ids_.size(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2784 |
return ids_[str] = id; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2785 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2786 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2787 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2788 |
typedef std::map<std::string, size_t> IdMap; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2789 |
IdMap ids_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2790 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2791 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2792 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2793 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2794 |
std::vector<EditType> CalculateOptimalEdits( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2795 |
const std::vector<std::string>& left, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2796 |
const std::vector<std::string>& right) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2797 |
std::vector<size_t> left_ids, right_ids; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2798 |
{ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2799 |
InternalStrings intern_table; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2800 |
for (size_t i = 0; i < left.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2801 |
left_ids.push_back(intern_table.GetId(left[i])); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2802 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2803 |
for (size_t i = 0; i < right.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2804 |
right_ids.push_back(intern_table.GetId(right[i])); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2805 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2806 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2807 |
return CalculateOptimalEdits(left_ids, right_ids); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2808 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2809 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2810 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2811 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2812 |
// Helper class that holds the state for one hunk and prints it out to the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2813 |
// stream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2814 |
// It reorders adds/removes when possible to group all removes before all |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2815 |
// adds. It also adds the hunk header before printint into the stream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2816 |
class Hunk { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2817 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2818 |
Hunk(size_t left_start, size_t right_start) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2819 |
: left_start_(left_start), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2820 |
right_start_(right_start), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2821 |
adds_(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2822 |
removes_(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2823 |
common_() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2824 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2825 |
void PushLine(char edit, const char* line) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2826 |
switch (edit) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2827 |
case ' ': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2828 |
++common_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2829 |
FlushEdits(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2830 |
hunk_.push_back(std::make_pair(' ', line)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2831 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2832 |
case '-': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2833 |
++removes_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2834 |
hunk_removes_.push_back(std::make_pair('-', line)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2835 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2836 |
case '+': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2837 |
++adds_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2838 |
hunk_adds_.push_back(std::make_pair('+', line)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2839 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2840 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2841 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2842 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2843 |
void PrintTo(std::ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2844 |
PrintHeader(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2845 |
FlushEdits(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2846 |
for (std::list<std::pair<char, const char*> >::const_iterator it = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2847 |
hunk_.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2848 |
it != hunk_.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2849 |
*os << it->first << it->second << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2850 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2851 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2852 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2853 |
bool has_edits() const { return adds_ || removes_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2854 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2855 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2856 |
void FlushEdits() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2857 |
hunk_.splice(hunk_.end(), hunk_removes_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2858 |
hunk_.splice(hunk_.end(), hunk_adds_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2859 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2860 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2861 |
// Print a unified diff header for one hunk. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2862 |
// The format is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2863 |
// "@@ -<left_start>,<left_length> +<right_start>,<right_length> @@" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2864 |
// where the left/right parts are omitted if unnecessary. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2865 |
void PrintHeader(std::ostream* ss) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2866 |
*ss << "@@ "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2867 |
if (removes_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2868 |
*ss << "-" << left_start_ << "," << (removes_ + common_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2869 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2870 |
if (removes_ && adds_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2871 |
*ss << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2872 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2873 |
if (adds_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2874 |
*ss << "+" << right_start_ << "," << (adds_ + common_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2875 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2876 |
*ss << " @@\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2877 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2878 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2879 |
size_t left_start_, right_start_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2880 |
size_t adds_, removes_, common_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2881 |
std::list<std::pair<char, const char*> > hunk_, hunk_adds_, hunk_removes_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2882 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2883 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2884 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2885 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2886 |
// Create a list of diff hunks in Unified diff format. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2887 |
// Each hunk has a header generated by PrintHeader above plus a body with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2888 |
// lines prefixed with ' ' for no change, '-' for deletion and '+' for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2889 |
// addition. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2890 |
// 'context' represents the desired unchanged prefix/suffix around the diff. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2891 |
// If two hunks are close enough that their contexts overlap, then they are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2892 |
// joined into one hunk. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2893 |
std::string CreateUnifiedDiff(const std::vector<std::string>& left, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2894 |
const std::vector<std::string>& right, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2895 |
size_t context) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2896 |
const std::vector<EditType> edits = CalculateOptimalEdits(left, right); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2897 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2898 |
size_t l_i = 0, r_i = 0, edit_i = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2899 |
std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2900 |
while (edit_i < edits.size()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2901 |
// Find first edit. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2902 |
while (edit_i < edits.size() && edits[edit_i] == kMatch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2903 |
++l_i; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2904 |
++r_i; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2905 |
++edit_i; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2906 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2907 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2908 |
// Find the first line to include in the hunk. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2909 |
const size_t prefix_context = std::min(l_i, context); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2910 |
Hunk hunk(l_i - prefix_context + 1, r_i - prefix_context + 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2911 |
for (size_t i = prefix_context; i > 0; --i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2912 |
hunk.PushLine(' ', left[l_i - i].c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2913 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2914 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2915 |
// Iterate the edits until we found enough suffix for the hunk or the input |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2916 |
// is over. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2917 |
size_t n_suffix = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2918 |
for (; edit_i < edits.size(); ++edit_i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2919 |
if (n_suffix >= context) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2920 |
// Continue only if the next hunk is very close. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2921 |
auto it = edits.begin() + static_cast<int>(edit_i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2922 |
while (it != edits.end() && *it == kMatch) ++it; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2923 |
if (it == edits.end() || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2924 |
static_cast<size_t>(it - edits.begin()) - edit_i >= context) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2925 |
// There is no next edit or it is too far away. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2926 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2927 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2928 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2929 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2930 |
EditType edit = edits[edit_i]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2931 |
// Reset count when a non match is found. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2932 |
n_suffix = edit == kMatch ? n_suffix + 1 : 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2933 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2934 |
if (edit == kMatch || edit == kRemove || edit == kReplace) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2935 |
hunk.PushLine(edit == kMatch ? ' ' : '-', left[l_i].c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2936 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2937 |
if (edit == kAdd || edit == kReplace) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2938 |
hunk.PushLine('+', right[r_i].c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2939 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2940 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2941 |
// Advance indices, depending on edit type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2942 |
l_i += edit != kAdd; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2943 |
r_i += edit != kRemove; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2944 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2945 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2946 |
if (!hunk.has_edits()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2947 |
// We are done. We don't want this hunk. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2948 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2949 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2950 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2951 |
hunk.PrintTo(&ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2952 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2953 |
return ss.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2954 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2955 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2956 |
} // namespace edit_distance |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2957 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2958 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2959 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2960 |
// The string representation of the values received in EqFailure() are already |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2961 |
// escaped. Split them on escaped '\n' boundaries. Leave all other escaped |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2962 |
// characters the same. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2963 |
std::vector<std::string> SplitEscapedString(const std::string& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2964 |
std::vector<std::string> lines; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2965 |
size_t start = 0, end = str.size(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2966 |
if (end > 2 && str[0] == '"' && str[end - 1] == '"') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2967 |
++start; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2968 |
--end; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2969 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2970 |
bool escaped = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2971 |
for (size_t i = start; i + 1 < end; ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2972 |
if (escaped) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2973 |
escaped = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2974 |
if (str[i] == 'n') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2975 |
lines.push_back(str.substr(start, i - start - 1)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2976 |
start = i + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2977 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2978 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2979 |
escaped = str[i] == '\\'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2980 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2981 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2982 |
lines.push_back(str.substr(start, end - start)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2983 |
return lines; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2984 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2985 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2986 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2987 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2988 |
// Constructs and returns the message for an equality assertion |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2989 |
// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2990 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2991 |
// The first four parameters are the expressions used in the assertion |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2992 |
// and their values, as strings. For example, for ASSERT_EQ(foo, bar) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2993 |
// where foo is 5 and bar is 6, we have: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2994 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2995 |
// lhs_expression: "foo" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2996 |
// rhs_expression: "bar" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2997 |
// lhs_value: "5" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2998 |
// rhs_value: "6" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2999 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3000 |
// The ignoring_case parameter is true if and only if the assertion is a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3001 |
// *_STRCASEEQ*. When it's true, the string "Ignoring case" will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3002 |
// be inserted into the message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3003 |
AssertionResult EqFailure(const char* lhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3004 |
const char* rhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3005 |
const std::string& lhs_value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3006 |
const std::string& rhs_value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3007 |
bool ignoring_case) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3008 |
Message msg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3009 |
msg << "Expected equality of these values:"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3010 |
msg << "\n " << lhs_expression; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3011 |
if (lhs_value != lhs_expression) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3012 |
msg << "\n Which is: " << lhs_value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3013 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3014 |
msg << "\n " << rhs_expression; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3015 |
if (rhs_value != rhs_expression) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3016 |
msg << "\n Which is: " << rhs_value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3017 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3018 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3019 |
if (ignoring_case) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3020 |
msg << "\nIgnoring case"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3021 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3022 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3023 |
if (!lhs_value.empty() && !rhs_value.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3024 |
const std::vector<std::string> lhs_lines = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3025 |
SplitEscapedString(lhs_value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3026 |
const std::vector<std::string> rhs_lines = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3027 |
SplitEscapedString(rhs_value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3028 |
if (lhs_lines.size() > 1 || rhs_lines.size() > 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3029 |
msg << "\nWith diff:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3030 |
<< edit_distance::CreateUnifiedDiff(lhs_lines, rhs_lines); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3031 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3032 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3033 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3034 |
return AssertionFailure() << msg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3035 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3036 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3037 |
// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3038 |
std::string GetBoolAssertionFailureMessage( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3039 |
const AssertionResult& assertion_result, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3040 |
const char* expression_text, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3041 |
const char* actual_predicate_value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3042 |
const char* expected_predicate_value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3043 |
const char* actual_message = assertion_result.message(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3044 |
Message msg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3045 |
msg << "Value of: " << expression_text |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3046 |
<< "\n Actual: " << actual_predicate_value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3047 |
if (actual_message[0] != '\0') |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3048 |
msg << " (" << actual_message << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3049 |
msg << "\nExpected: " << expected_predicate_value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3050 |
return msg.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3051 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3052 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3053 |
// Helper function for implementing ASSERT_NEAR. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3054 |
AssertionResult DoubleNearPredFormat(const char* expr1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3055 |
const char* expr2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3056 |
const char* abs_error_expr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3057 |
double val1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3058 |
double val2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3059 |
double abs_error) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3060 |
const double diff = fabs(val1 - val2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3061 |
if (diff <= abs_error) return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3062 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3063 |
// Find the value which is closest to zero. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3064 |
const double min_abs = std::min(fabs(val1), fabs(val2)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3065 |
// Find the distance to the next double from that value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3066 |
const double epsilon = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3067 |
nextafter(min_abs, std::numeric_limits<double>::infinity()) - min_abs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3068 |
// Detect the case where abs_error is so small that EXPECT_NEAR is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3069 |
// effectively the same as EXPECT_EQUAL, and give an informative error |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3070 |
// message so that the situation can be more easily understood without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3071 |
// requiring exotic floating-point knowledge. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3072 |
// Don't do an epsilon check if abs_error is zero because that implies |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3073 |
// that an equality check was actually intended. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3074 |
if (!(std::isnan)(val1) && !(std::isnan)(val2) && abs_error > 0 && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3075 |
abs_error < epsilon) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3076 |
return AssertionFailure() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3077 |
<< "The difference between " << expr1 << " and " << expr2 << " is " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3078 |
<< diff << ", where\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3079 |
<< expr1 << " evaluates to " << val1 << ",\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3080 |
<< expr2 << " evaluates to " << val2 << ".\nThe abs_error parameter " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3081 |
<< abs_error_expr << " evaluates to " << abs_error |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3082 |
<< " which is smaller than the minimum distance between doubles for " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3083 |
"numbers of this magnitude which is " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3084 |
<< epsilon |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3085 |
<< ", thus making this EXPECT_NEAR check equivalent to " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3086 |
"EXPECT_EQUAL. Consider using EXPECT_DOUBLE_EQ instead."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3087 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3088 |
return AssertionFailure() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3089 |
<< "The difference between " << expr1 << " and " << expr2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3090 |
<< " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3091 |
<< expr1 << " evaluates to " << val1 << ",\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3092 |
<< expr2 << " evaluates to " << val2 << ", and\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3093 |
<< abs_error_expr << " evaluates to " << abs_error << "."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3094 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3095 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3096 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3097 |
// Helper template for implementing FloatLE() and DoubleLE(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3098 |
template <typename RawType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3099 |
AssertionResult FloatingPointLE(const char* expr1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3100 |
const char* expr2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3101 |
RawType val1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3102 |
RawType val2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3103 |
// Returns success if val1 is less than val2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3104 |
if (val1 < val2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3105 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3106 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3107 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3108 |
// or if val1 is almost equal to val2. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3109 |
const FloatingPoint<RawType> lhs(val1), rhs(val2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3110 |
if (lhs.AlmostEquals(rhs)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3111 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3112 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3113 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3114 |
// Note that the above two checks will both fail if either val1 or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3115 |
// val2 is NaN, as the IEEE floating-point standard requires that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3116 |
// any predicate involving a NaN must return false. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3117 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3118 |
::std::stringstream val1_ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3119 |
val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3120 |
<< val1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3121 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3122 |
::std::stringstream val2_ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3123 |
val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3124 |
<< val2; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3125 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3126 |
return AssertionFailure() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3127 |
<< "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3128 |
<< " Actual: " << StringStreamToString(&val1_ss) << " vs " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3129 |
<< StringStreamToString(&val2_ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3130 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3131 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3132 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3133 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3134 |
// Asserts that val1 is less than, or almost equal to, val2. Fails |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3135 |
// otherwise. In particular, it fails if either val1 or val2 is NaN. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3136 |
AssertionResult FloatLE(const char* expr1, const char* expr2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3137 |
float val1, float val2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3138 |
return internal::FloatingPointLE<float>(expr1, expr2, val1, val2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3139 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3140 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3141 |
// Asserts that val1 is less than, or almost equal to, val2. Fails |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3142 |
// otherwise. In particular, it fails if either val1 or val2 is NaN. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3143 |
AssertionResult DoubleLE(const char* expr1, const char* expr2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3144 |
double val1, double val2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3145 |
return internal::FloatingPointLE<double>(expr1, expr2, val1, val2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3146 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3147 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3148 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3149 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3150 |
// The helper function for {ASSERT|EXPECT}_STREQ. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3151 |
AssertionResult CmpHelperSTREQ(const char* lhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3152 |
const char* rhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3153 |
const char* lhs, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3154 |
const char* rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3155 |
if (String::CStringEquals(lhs, rhs)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3156 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3157 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3158 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3159 |
return EqFailure(lhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3160 |
rhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3161 |
PrintToString(lhs), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3162 |
PrintToString(rhs), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3163 |
false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3164 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3165 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3166 |
// The helper function for {ASSERT|EXPECT}_STRCASEEQ. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3167 |
AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3168 |
const char* rhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3169 |
const char* lhs, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3170 |
const char* rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3171 |
if (String::CaseInsensitiveCStringEquals(lhs, rhs)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3172 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3173 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3174 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3175 |
return EqFailure(lhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3176 |
rhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3177 |
PrintToString(lhs), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3178 |
PrintToString(rhs), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3179 |
true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3180 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3181 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3182 |
// The helper function for {ASSERT|EXPECT}_STRNE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3183 |
AssertionResult CmpHelperSTRNE(const char* s1_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3184 |
const char* s2_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3185 |
const char* s1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3186 |
const char* s2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3187 |
if (!String::CStringEquals(s1, s2)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3188 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3189 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3190 |
return AssertionFailure() << "Expected: (" << s1_expression << ") != (" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3191 |
<< s2_expression << "), actual: \"" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3192 |
<< s1 << "\" vs \"" << s2 << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3193 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3194 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3195 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3196 |
// The helper function for {ASSERT|EXPECT}_STRCASENE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3197 |
AssertionResult CmpHelperSTRCASENE(const char* s1_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3198 |
const char* s2_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3199 |
const char* s1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3200 |
const char* s2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3201 |
if (!String::CaseInsensitiveCStringEquals(s1, s2)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3202 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3203 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3204 |
return AssertionFailure() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3205 |
<< "Expected: (" << s1_expression << ") != (" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3206 |
<< s2_expression << ") (ignoring case), actual: \"" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3207 |
<< s1 << "\" vs \"" << s2 << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3208 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3209 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3210 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3211 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3212 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3213 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3214 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3215 |
// Helper functions for implementing IsSubString() and IsNotSubstring(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3216 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3217 |
// This group of overloaded functions return true if and only if needle |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3218 |
// is a substring of haystack. NULL is considered a substring of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3219 |
// itself only. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3220 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3221 |
bool IsSubstringPred(const char* needle, const char* haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3222 |
if (needle == nullptr || haystack == nullptr) return needle == haystack; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3223 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3224 |
return strstr(haystack, needle) != nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3225 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3226 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3227 |
bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3228 |
if (needle == nullptr || haystack == nullptr) return needle == haystack; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3229 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3230 |
return wcsstr(haystack, needle) != nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3231 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3232 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3233 |
// StringType here can be either ::std::string or ::std::wstring. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3234 |
template <typename StringType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3235 |
bool IsSubstringPred(const StringType& needle, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3236 |
const StringType& haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3237 |
return haystack.find(needle) != StringType::npos; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3238 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3239 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3240 |
// This function implements either IsSubstring() or IsNotSubstring(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3241 |
// depending on the value of the expected_to_be_substring parameter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3242 |
// StringType here can be const char*, const wchar_t*, ::std::string, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3243 |
// or ::std::wstring. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3244 |
template <typename StringType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3245 |
AssertionResult IsSubstringImpl( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3246 |
bool expected_to_be_substring, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3247 |
const char* needle_expr, const char* haystack_expr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3248 |
const StringType& needle, const StringType& haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3249 |
if (IsSubstringPred(needle, haystack) == expected_to_be_substring) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3250 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3251 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3252 |
const bool is_wide_string = sizeof(needle[0]) > 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3253 |
const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3254 |
return AssertionFailure() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3255 |
<< "Value of: " << needle_expr << "\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3256 |
<< " Actual: " << begin_string_quote << needle << "\"\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3257 |
<< "Expected: " << (expected_to_be_substring ? "" : "not ") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3258 |
<< "a substring of " << haystack_expr << "\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3259 |
<< "Which is: " << begin_string_quote << haystack << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3260 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3261 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3262 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3263 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3264 |
// IsSubstring() and IsNotSubstring() check whether needle is a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3265 |
// substring of haystack (NULL is considered a substring of itself |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3266 |
// only), and return an appropriate error message when they fail. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3267 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3268 |
AssertionResult IsSubstring( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3269 |
const char* needle_expr, const char* haystack_expr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3270 |
const char* needle, const char* haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3271 |
return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3272 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3273 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3274 |
AssertionResult IsSubstring( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3275 |
const char* needle_expr, const char* haystack_expr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3276 |
const wchar_t* needle, const wchar_t* haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3277 |
return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3278 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3279 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3280 |
AssertionResult IsNotSubstring( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3281 |
const char* needle_expr, const char* haystack_expr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3282 |
const char* needle, const char* haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3283 |
return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3284 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3285 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3286 |
AssertionResult IsNotSubstring( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3287 |
const char* needle_expr, const char* haystack_expr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3288 |
const wchar_t* needle, const wchar_t* haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3289 |
return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3290 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3291 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3292 |
AssertionResult IsSubstring( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3293 |
const char* needle_expr, const char* haystack_expr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3294 |
const ::std::string& needle, const ::std::string& haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3295 |
return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3296 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3297 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3298 |
AssertionResult IsNotSubstring( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3299 |
const char* needle_expr, const char* haystack_expr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3300 |
const ::std::string& needle, const ::std::string& haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3301 |
return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3302 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3303 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3304 |
#if GTEST_HAS_STD_WSTRING |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3305 |
AssertionResult IsSubstring( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3306 |
const char* needle_expr, const char* haystack_expr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3307 |
const ::std::wstring& needle, const ::std::wstring& haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3308 |
return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3309 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3310 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3311 |
AssertionResult IsNotSubstring( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3312 |
const char* needle_expr, const char* haystack_expr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3313 |
const ::std::wstring& needle, const ::std::wstring& haystack) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3314 |
return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3315 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3316 |
#endif // GTEST_HAS_STD_WSTRING |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3317 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3318 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3319 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3320 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3321 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3322 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3323 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3324 |
// Helper function for IsHRESULT{SuccessFailure} predicates |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3325 |
AssertionResult HRESULTFailureHelper(const char* expr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3326 |
const char* expected, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3327 |
long hr) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3328 |
# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_TV_TITLE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3329 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3330 |
// Windows CE doesn't support FormatMessage. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3331 |
const char error_text[] = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3332 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3333 |
# else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3334 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3335 |
// Looks up the human-readable system message for the HRESULT code |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3336 |
// and since we're not passing any params to FormatMessage, we don't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3337 |
// want inserts expanded. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3338 |
const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3339 |
FORMAT_MESSAGE_IGNORE_INSERTS; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3340 |
const DWORD kBufSize = 4096; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3341 |
// Gets the system's human readable message string for this HRESULT. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3342 |
char error_text[kBufSize] = { '\0' }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3343 |
DWORD message_length = ::FormatMessageA(kFlags, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3344 |
0, // no source, we're asking system |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3345 |
static_cast<DWORD>(hr), // the error |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3346 |
0, // no line width restrictions |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3347 |
error_text, // output buffer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3348 |
kBufSize, // buf size |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3349 |
nullptr); // no arguments for inserts |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3350 |
// Trims tailing white space (FormatMessage leaves a trailing CR-LF) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3351 |
for (; message_length && IsSpace(error_text[message_length - 1]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3352 |
--message_length) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3353 |
error_text[message_length - 1] = '\0'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3354 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3355 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3356 |
# endif // GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3357 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3358 |
const std::string error_hex("0x" + String::FormatHexInt(hr)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3359 |
return ::testing::AssertionFailure() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3360 |
<< "Expected: " << expr << " " << expected << ".\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3361 |
<< " Actual: " << error_hex << " " << error_text << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3362 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3363 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3364 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3365 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3366 |
AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3367 |
if (SUCCEEDED(hr)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3368 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3369 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3370 |
return HRESULTFailureHelper(expr, "succeeds", hr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3371 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3372 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3373 |
AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3374 |
if (FAILED(hr)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3375 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3376 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3377 |
return HRESULTFailureHelper(expr, "fails", hr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3378 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3379 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3380 |
#endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3381 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3382 |
// Utility functions for encoding Unicode text (wide strings) in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3383 |
// UTF-8. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3384 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3385 |
// A Unicode code-point can have up to 21 bits, and is encoded in UTF-8 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3386 |
// like this: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3387 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3388 |
// Code-point length Encoding |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3389 |
// 0 - 7 bits 0xxxxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3390 |
// 8 - 11 bits 110xxxxx 10xxxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3391 |
// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3392 |
// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3393 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3394 |
// The maximum code-point a one-byte UTF-8 sequence can represent. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3395 |
constexpr uint32_t kMaxCodePoint1 = (static_cast<uint32_t>(1) << 7) - 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3396 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3397 |
// The maximum code-point a two-byte UTF-8 sequence can represent. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3398 |
constexpr uint32_t kMaxCodePoint2 = (static_cast<uint32_t>(1) << (5 + 6)) - 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3399 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3400 |
// The maximum code-point a three-byte UTF-8 sequence can represent. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3401 |
constexpr uint32_t kMaxCodePoint3 = (static_cast<uint32_t>(1) << (4 + 2*6)) - 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3402 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3403 |
// The maximum code-point a four-byte UTF-8 sequence can represent. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3404 |
constexpr uint32_t kMaxCodePoint4 = (static_cast<uint32_t>(1) << (3 + 3*6)) - 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3405 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3406 |
// Chops off the n lowest bits from a bit pattern. Returns the n |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3407 |
// lowest bits. As a side effect, the original bit pattern will be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3408 |
// shifted to the right by n bits. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3409 |
inline uint32_t ChopLowBits(uint32_t* bits, int n) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3410 |
const uint32_t low_bits = *bits & ((static_cast<uint32_t>(1) << n) - 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3411 |
*bits >>= n; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3412 |
return low_bits; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3413 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3414 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3415 |
// Converts a Unicode code point to a narrow string in UTF-8 encoding. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3416 |
// code_point parameter is of type uint32_t because wchar_t may not be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3417 |
// wide enough to contain a code point. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3418 |
// If the code_point is not a valid Unicode code point |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3419 |
// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3420 |
// to "(Invalid Unicode 0xXXXXXXXX)". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3421 |
std::string CodePointToUtf8(uint32_t code_point) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3422 |
if (code_point > kMaxCodePoint4) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3423 |
return "(Invalid Unicode 0x" + String::FormatHexUInt32(code_point) + ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3424 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3425 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3426 |
char str[5]; // Big enough for the largest valid code point. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3427 |
if (code_point <= kMaxCodePoint1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3428 |
str[1] = '\0'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3429 |
str[0] = static_cast<char>(code_point); // 0xxxxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3430 |
} else if (code_point <= kMaxCodePoint2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3431 |
str[2] = '\0'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3432 |
str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3433 |
str[0] = static_cast<char>(0xC0 | code_point); // 110xxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3434 |
} else if (code_point <= kMaxCodePoint3) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3435 |
str[3] = '\0'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3436 |
str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3437 |
str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3438 |
str[0] = static_cast<char>(0xE0 | code_point); // 1110xxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3439 |
} else { // code_point <= kMaxCodePoint4 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3440 |
str[4] = '\0'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3441 |
str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3442 |
str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3443 |
str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3444 |
str[0] = static_cast<char>(0xF0 | code_point); // 11110xxx |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3445 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3446 |
return str; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3447 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3448 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3449 |
// The following two functions only make sense if the system |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3450 |
// uses UTF-16 for wide string encoding. All supported systems |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3451 |
// with 16 bit wchar_t (Windows, Cygwin) do use UTF-16. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3452 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3453 |
// Determines if the arguments constitute UTF-16 surrogate pair |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3454 |
// and thus should be combined into a single Unicode code point |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3455 |
// using CreateCodePointFromUtf16SurrogatePair. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3456 |
inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3457 |
return sizeof(wchar_t) == 2 && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3458 |
(first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3459 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3460 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3461 |
// Creates a Unicode code point from UTF16 surrogate pair. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3462 |
inline uint32_t CreateCodePointFromUtf16SurrogatePair(wchar_t first, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3463 |
wchar_t second) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3464 |
const auto first_u = static_cast<uint32_t>(first); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3465 |
const auto second_u = static_cast<uint32_t>(second); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3466 |
const uint32_t mask = (1 << 10) - 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3467 |
return (sizeof(wchar_t) == 2) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3468 |
? (((first_u & mask) << 10) | (second_u & mask)) + 0x10000 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3469 |
: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3470 |
// This function should not be called when the condition is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3471 |
// false, but we provide a sensible default in case it is. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3472 |
first_u; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3473 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3474 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3475 |
// Converts a wide string to a narrow string in UTF-8 encoding. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3476 |
// The wide string is assumed to have the following encoding: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3477 |
// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3478 |
// UTF-32 if sizeof(wchar_t) == 4 (on Linux) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3479 |
// Parameter str points to a null-terminated wide string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3480 |
// Parameter num_chars may additionally limit the number |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3481 |
// of wchar_t characters processed. -1 is used when the entire string |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3482 |
// should be processed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3483 |
// If the string contains code points that are not valid Unicode code points |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3484 |
// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3485 |
// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3486 |
// and contains invalid UTF-16 surrogate pairs, values in those pairs |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3487 |
// will be encoded as individual Unicode characters from Basic Normal Plane. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3488 |
std::string WideStringToUtf8(const wchar_t* str, int num_chars) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3489 |
if (num_chars == -1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3490 |
num_chars = static_cast<int>(wcslen(str)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3491 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3492 |
::std::stringstream stream; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3493 |
for (int i = 0; i < num_chars; ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3494 |
uint32_t unicode_code_point; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3495 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3496 |
if (str[i] == L'\0') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3497 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3498 |
} else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3499 |
unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3500 |
str[i + 1]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3501 |
i++; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3502 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3503 |
unicode_code_point = static_cast<uint32_t>(str[i]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3504 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3505 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3506 |
stream << CodePointToUtf8(unicode_code_point); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3507 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3508 |
return StringStreamToString(&stream); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3509 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3510 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3511 |
// Converts a wide C string to an std::string using the UTF-8 encoding. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3512 |
// NULL will be converted to "(null)". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3513 |
std::string String::ShowWideCString(const wchar_t * wide_c_str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3514 |
if (wide_c_str == nullptr) return "(null)"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3515 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3516 |
return internal::WideStringToUtf8(wide_c_str, -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3517 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3518 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3519 |
// Compares two wide C strings. Returns true if and only if they have the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3520 |
// same content. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3521 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3522 |
// Unlike wcscmp(), this function can handle NULL argument(s). A NULL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3523 |
// C string is considered different to any non-NULL C string, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3524 |
// including the empty string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3525 |
bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3526 |
if (lhs == nullptr) return rhs == nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3527 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3528 |
if (rhs == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3529 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3530 |
return wcscmp(lhs, rhs) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3531 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3532 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3533 |
// Helper function for *_STREQ on wide strings. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3534 |
AssertionResult CmpHelperSTREQ(const char* lhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3535 |
const char* rhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3536 |
const wchar_t* lhs, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3537 |
const wchar_t* rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3538 |
if (String::WideCStringEquals(lhs, rhs)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3539 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3540 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3541 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3542 |
return EqFailure(lhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3543 |
rhs_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3544 |
PrintToString(lhs), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3545 |
PrintToString(rhs), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3546 |
false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3547 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3548 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3549 |
// Helper function for *_STRNE on wide strings. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3550 |
AssertionResult CmpHelperSTRNE(const char* s1_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3551 |
const char* s2_expression, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3552 |
const wchar_t* s1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3553 |
const wchar_t* s2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3554 |
if (!String::WideCStringEquals(s1, s2)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3555 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3556 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3557 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3558 |
return AssertionFailure() << "Expected: (" << s1_expression << ") != (" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3559 |
<< s2_expression << "), actual: " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3560 |
<< PrintToString(s1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3561 |
<< " vs " << PrintToString(s2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3562 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3563 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3564 |
// Compares two C strings, ignoring case. Returns true if and only if they have |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3565 |
// the same content. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3566 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3567 |
// Unlike strcasecmp(), this function can handle NULL argument(s). A |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3568 |
// NULL C string is considered different to any non-NULL C string, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3569 |
// including the empty string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3570 |
bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3571 |
if (lhs == nullptr) return rhs == nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3572 |
if (rhs == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3573 |
return posix::StrCaseCmp(lhs, rhs) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3574 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3575 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3576 |
// Compares two wide C strings, ignoring case. Returns true if and only if they |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3577 |
// have the same content. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3578 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3579 |
// Unlike wcscasecmp(), this function can handle NULL argument(s). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3580 |
// A NULL C string is considered different to any non-NULL wide C string, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3581 |
// including the empty string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3582 |
// NB: The implementations on different platforms slightly differ. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3583 |
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3584 |
// environment variable. On GNU platform this method uses wcscasecmp |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3585 |
// which compares according to LC_CTYPE category of the current locale. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3586 |
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3587 |
// current locale. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3588 |
bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3589 |
const wchar_t* rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3590 |
if (lhs == nullptr) return rhs == nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3591 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3592 |
if (rhs == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3593 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3594 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3595 |
return _wcsicmp(lhs, rhs) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3596 |
#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3597 |
return wcscasecmp(lhs, rhs) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3598 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3599 |
// Android, Mac OS X and Cygwin don't define wcscasecmp. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3600 |
// Other unknown OSes may not define it either. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3601 |
wint_t left, right; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3602 |
do { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3603 |
left = towlower(static_cast<wint_t>(*lhs++)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3604 |
right = towlower(static_cast<wint_t>(*rhs++)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3605 |
} while (left && left == right); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3606 |
return left == right; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3607 |
#endif // OS selector |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3608 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3609 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3610 |
// Returns true if and only if str ends with the given suffix, ignoring case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3611 |
// Any string is considered to end with an empty suffix. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3612 |
bool String::EndsWithCaseInsensitive( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3613 |
const std::string& str, const std::string& suffix) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3614 |
const size_t str_len = str.length(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3615 |
const size_t suffix_len = suffix.length(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3616 |
return (str_len >= suffix_len) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3617 |
CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3618 |
suffix.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3619 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3620 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3621 |
// Formats an int value as "%02d". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3622 |
std::string String::FormatIntWidth2(int value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3623 |
return FormatIntWidthN(value, 2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3624 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3625 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3626 |
// Formats an int value to given width with leading zeros. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3627 |
std::string String::FormatIntWidthN(int value, int width) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3628 |
std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3629 |
ss << std::setfill('0') << std::setw(width) << value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3630 |
return ss.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3631 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3632 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3633 |
// Formats an int value as "%X". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3634 |
std::string String::FormatHexUInt32(uint32_t value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3635 |
std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3636 |
ss << std::hex << std::uppercase << value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3637 |
return ss.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3638 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3639 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3640 |
// Formats an int value as "%X". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3641 |
std::string String::FormatHexInt(int value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3642 |
return FormatHexUInt32(static_cast<uint32_t>(value)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3643 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3644 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3645 |
// Formats a byte as "%02X". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3646 |
std::string String::FormatByte(unsigned char value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3647 |
std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3648 |
ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3649 |
<< static_cast<unsigned int>(value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3650 |
return ss.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3651 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3652 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3653 |
// Converts the buffer in a stringstream to an std::string, converting NUL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3654 |
// bytes to "\\0" along the way. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3655 |
std::string StringStreamToString(::std::stringstream* ss) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3656 |
const ::std::string& str = ss->str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3657 |
const char* const start = str.c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3658 |
const char* const end = start + str.length(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3659 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3660 |
std::string result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3661 |
result.reserve(static_cast<size_t>(2 * (end - start))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3662 |
for (const char* ch = start; ch != end; ++ch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3663 |
if (*ch == '\0') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3664 |
result += "\\0"; // Replaces NUL with "\\0"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3665 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3666 |
result += *ch; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3667 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3668 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3669 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3670 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3671 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3672 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3673 |
// Appends the user-supplied message to the Google-Test-generated message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3674 |
std::string AppendUserMessage(const std::string& gtest_msg, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3675 |
const Message& user_msg) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3676 |
// Appends the user message if it's non-empty. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3677 |
const std::string user_msg_string = user_msg.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3678 |
if (user_msg_string.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3679 |
return gtest_msg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3680 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3681 |
if (gtest_msg.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3682 |
return user_msg_string; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3683 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3684 |
return gtest_msg + "\n" + user_msg_string; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3685 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3686 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3687 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3688 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3689 |
// class TestResult |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3690 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3691 |
// Creates an empty TestResult. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3692 |
TestResult::TestResult() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3693 |
: death_test_count_(0), start_timestamp_(0), elapsed_time_(0) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3694 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3695 |
// D'tor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3696 |
TestResult::~TestResult() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3697 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3698 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3699 |
// Returns the i-th test part result among all the results. i can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3700 |
// range from 0 to total_part_count() - 1. If i is not in that range, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3701 |
// aborts the program. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3702 |
const TestPartResult& TestResult::GetTestPartResult(int i) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3703 |
if (i < 0 || i >= total_part_count()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3704 |
internal::posix::Abort(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3705 |
return test_part_results_.at(static_cast<size_t>(i)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3706 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3707 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3708 |
// Returns the i-th test property. i can range from 0 to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3709 |
// test_property_count() - 1. If i is not in that range, aborts the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3710 |
// program. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3711 |
const TestProperty& TestResult::GetTestProperty(int i) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3712 |
if (i < 0 || i >= test_property_count()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3713 |
internal::posix::Abort(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3714 |
return test_properties_.at(static_cast<size_t>(i)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3715 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3716 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3717 |
// Clears the test part results. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3718 |
void TestResult::ClearTestPartResults() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3719 |
test_part_results_.clear(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3720 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3721 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3722 |
// Adds a test part result to the list. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3723 |
void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3724 |
test_part_results_.push_back(test_part_result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3725 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3726 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3727 |
// Adds a test property to the list. If a property with the same key as the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3728 |
// supplied property is already represented, the value of this test_property |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3729 |
// replaces the old value for that key. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3730 |
void TestResult::RecordProperty(const std::string& xml_element, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3731 |
const TestProperty& test_property) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3732 |
if (!ValidateTestProperty(xml_element, test_property)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3733 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3734 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3735 |
internal::MutexLock lock(&test_properties_mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3736 |
const std::vector<TestProperty>::iterator property_with_matching_key = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3737 |
std::find_if(test_properties_.begin(), test_properties_.end(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3738 |
internal::TestPropertyKeyIs(test_property.key())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3739 |
if (property_with_matching_key == test_properties_.end()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3740 |
test_properties_.push_back(test_property); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3741 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3742 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3743 |
property_with_matching_key->SetValue(test_property.value()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3744 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3745 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3746 |
// The list of reserved attributes used in the <testsuites> element of XML |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3747 |
// output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3748 |
static const char* const kReservedTestSuitesAttributes[] = { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3749 |
"disabled", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3750 |
"errors", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3751 |
"failures", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3752 |
"name", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3753 |
"random_seed", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3754 |
"tests", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3755 |
"time", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3756 |
"timestamp" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3757 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3758 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3759 |
// The list of reserved attributes used in the <testsuite> element of XML |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3760 |
// output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3761 |
static const char* const kReservedTestSuiteAttributes[] = { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3762 |
"disabled", "errors", "failures", "name", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3763 |
"tests", "time", "timestamp", "skipped"}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3764 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3765 |
// The list of reserved attributes used in the <testcase> element of XML output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3766 |
static const char* const kReservedTestCaseAttributes[] = { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3767 |
"classname", "name", "status", "time", "type_param", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3768 |
"value_param", "file", "line"}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3769 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3770 |
// Use a slightly different set for allowed output to ensure existing tests can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3771 |
// still RecordProperty("result") or "RecordProperty(timestamp") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3772 |
static const char* const kReservedOutputTestCaseAttributes[] = { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3773 |
"classname", "name", "status", "time", "type_param", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3774 |
"value_param", "file", "line", "result", "timestamp"}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3775 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3776 |
template <size_t kSize> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3777 |
std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3778 |
return std::vector<std::string>(array, array + kSize); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3779 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3780 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3781 |
static std::vector<std::string> GetReservedAttributesForElement( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3782 |
const std::string& xml_element) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3783 |
if (xml_element == "testsuites") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3784 |
return ArrayAsVector(kReservedTestSuitesAttributes); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3785 |
} else if (xml_element == "testsuite") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3786 |
return ArrayAsVector(kReservedTestSuiteAttributes); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3787 |
} else if (xml_element == "testcase") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3788 |
return ArrayAsVector(kReservedTestCaseAttributes); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3789 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3790 |
GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3791 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3792 |
// This code is unreachable but some compilers may not realizes that. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3793 |
return std::vector<std::string>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3794 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3795 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3796 |
// TODO(jdesprez): Merge the two getReserved attributes once skip is improved |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3797 |
static std::vector<std::string> GetReservedOutputAttributesForElement( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3798 |
const std::string& xml_element) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3799 |
if (xml_element == "testsuites") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3800 |
return ArrayAsVector(kReservedTestSuitesAttributes); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3801 |
} else if (xml_element == "testsuite") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3802 |
return ArrayAsVector(kReservedTestSuiteAttributes); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3803 |
} else if (xml_element == "testcase") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3804 |
return ArrayAsVector(kReservedOutputTestCaseAttributes); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3805 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3806 |
GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3807 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3808 |
// This code is unreachable but some compilers may not realizes that. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3809 |
return std::vector<std::string>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3810 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3811 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3812 |
static std::string FormatWordList(const std::vector<std::string>& words) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3813 |
Message word_list; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3814 |
for (size_t i = 0; i < words.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3815 |
if (i > 0 && words.size() > 2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3816 |
word_list << ", "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3817 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3818 |
if (i == words.size() - 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3819 |
word_list << "and "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3820 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3821 |
word_list << "'" << words[i] << "'"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3822 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3823 |
return word_list.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3824 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3825 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3826 |
static bool ValidateTestPropertyName( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3827 |
const std::string& property_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3828 |
const std::vector<std::string>& reserved_names) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3829 |
if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3830 |
reserved_names.end()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3831 |
ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3832 |
<< " (" << FormatWordList(reserved_names) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3833 |
<< " are reserved by " << GTEST_NAME_ << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3834 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3835 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3836 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3837 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3838 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3839 |
// Adds a failure if the key is a reserved attribute of the element named |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3840 |
// xml_element. Returns true if the property is valid. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3841 |
bool TestResult::ValidateTestProperty(const std::string& xml_element, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3842 |
const TestProperty& test_property) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3843 |
return ValidateTestPropertyName(test_property.key(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3844 |
GetReservedAttributesForElement(xml_element)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3845 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3846 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3847 |
// Clears the object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3848 |
void TestResult::Clear() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3849 |
test_part_results_.clear(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3850 |
test_properties_.clear(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3851 |
death_test_count_ = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3852 |
elapsed_time_ = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3853 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3854 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3855 |
// Returns true off the test part was skipped. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3856 |
static bool TestPartSkipped(const TestPartResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3857 |
return result.skipped(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3858 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3859 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3860 |
// Returns true if and only if the test was skipped. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3861 |
bool TestResult::Skipped() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3862 |
return !Failed() && CountIf(test_part_results_, TestPartSkipped) > 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3863 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3864 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3865 |
// Returns true if and only if the test failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3866 |
bool TestResult::Failed() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3867 |
for (int i = 0; i < total_part_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3868 |
if (GetTestPartResult(i).failed()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3869 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3870 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3871 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3872 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3873 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3874 |
// Returns true if and only if the test part fatally failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3875 |
static bool TestPartFatallyFailed(const TestPartResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3876 |
return result.fatally_failed(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3877 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3878 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3879 |
// Returns true if and only if the test fatally failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3880 |
bool TestResult::HasFatalFailure() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3881 |
return CountIf(test_part_results_, TestPartFatallyFailed) > 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3882 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3883 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3884 |
// Returns true if and only if the test part non-fatally failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3885 |
static bool TestPartNonfatallyFailed(const TestPartResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3886 |
return result.nonfatally_failed(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3887 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3888 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3889 |
// Returns true if and only if the test has a non-fatal failure. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3890 |
bool TestResult::HasNonfatalFailure() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3891 |
return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3892 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3893 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3894 |
// Gets the number of all test parts. This is the sum of the number |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3895 |
// of successful test parts and the number of failed test parts. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3896 |
int TestResult::total_part_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3897 |
return static_cast<int>(test_part_results_.size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3898 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3899 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3900 |
// Returns the number of the test properties. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3901 |
int TestResult::test_property_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3902 |
return static_cast<int>(test_properties_.size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3903 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3904 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3905 |
// class Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3906 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3907 |
// Creates a Test object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3908 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3909 |
// The c'tor saves the states of all flags. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3910 |
Test::Test() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3911 |
: gtest_flag_saver_(new GTEST_FLAG_SAVER_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3912 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3913 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3914 |
// The d'tor restores the states of all flags. The actual work is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3915 |
// done by the d'tor of the gtest_flag_saver_ field, and thus not |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3916 |
// visible here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3917 |
Test::~Test() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3918 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3919 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3920 |
// Sets up the test fixture. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3921 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3922 |
// A sub-class may override this. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3923 |
void Test::SetUp() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3924 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3925 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3926 |
// Tears down the test fixture. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3927 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3928 |
// A sub-class may override this. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3929 |
void Test::TearDown() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3930 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3931 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3932 |
// Allows user supplied key value pairs to be recorded for later output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3933 |
void Test::RecordProperty(const std::string& key, const std::string& value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3934 |
UnitTest::GetInstance()->RecordProperty(key, value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3935 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3936 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3937 |
// Allows user supplied key value pairs to be recorded for later output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3938 |
void Test::RecordProperty(const std::string& key, int value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3939 |
Message value_message; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3940 |
value_message << value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3941 |
RecordProperty(key, value_message.GetString().c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3942 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3943 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3944 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3945 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3946 |
void ReportFailureInUnknownLocation(TestPartResult::Type result_type, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3947 |
const std::string& message) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3948 |
// This function is a friend of UnitTest and as such has access to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3949 |
// AddTestPartResult. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3950 |
UnitTest::GetInstance()->AddTestPartResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3951 |
result_type, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3952 |
nullptr, // No info about the source file where the exception occurred. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3953 |
-1, // We have no info on which line caused the exception. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3954 |
message, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3955 |
""); // No stack trace, either. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3956 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3957 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3958 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3959 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3960 |
// Google Test requires all tests in the same test suite to use the same test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3961 |
// fixture class. This function checks if the current test has the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3962 |
// same fixture class as the first test in the current test suite. If |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3963 |
// yes, it returns true; otherwise it generates a Google Test failure and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3964 |
// returns false. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3965 |
bool Test::HasSameFixtureClass() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3966 |
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3967 |
const TestSuite* const test_suite = impl->current_test_suite(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3968 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3969 |
// Info about the first test in the current test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3970 |
const TestInfo* const first_test_info = test_suite->test_info_list()[0]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3971 |
const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3972 |
const char* const first_test_name = first_test_info->name(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3973 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3974 |
// Info about the current test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3975 |
const TestInfo* const this_test_info = impl->current_test_info(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3976 |
const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3977 |
const char* const this_test_name = this_test_info->name(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3978 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3979 |
if (this_fixture_id != first_fixture_id) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3980 |
// Is the first test defined using TEST? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3981 |
const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3982 |
// Is this test defined using TEST? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3983 |
const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3984 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3985 |
if (first_is_TEST || this_is_TEST) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3986 |
// Both TEST and TEST_F appear in same test suite, which is incorrect. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3987 |
// Tell the user how to fix this. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3988 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3989 |
// Gets the name of the TEST and the name of the TEST_F. Note |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3990 |
// that first_is_TEST and this_is_TEST cannot both be true, as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3991 |
// the fixture IDs are different for the two tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3992 |
const char* const TEST_name = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3993 |
first_is_TEST ? first_test_name : this_test_name; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3994 |
const char* const TEST_F_name = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3995 |
first_is_TEST ? this_test_name : first_test_name; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3996 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3997 |
ADD_FAILURE() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3998 |
<< "All tests in the same test suite must use the same test fixture\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3999 |
<< "class, so mixing TEST_F and TEST in the same test suite is\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4000 |
<< "illegal. In test suite " << this_test_info->test_suite_name() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4001 |
<< ",\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4002 |
<< "test " << TEST_F_name << " is defined using TEST_F but\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4003 |
<< "test " << TEST_name << " is defined using TEST. You probably\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4004 |
<< "want to change the TEST to TEST_F or move it to another test\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4005 |
<< "case."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4006 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4007 |
// Two fixture classes with the same name appear in two different |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4008 |
// namespaces, which is not allowed. Tell the user how to fix this. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4009 |
ADD_FAILURE() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4010 |
<< "All tests in the same test suite must use the same test fixture\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4011 |
<< "class. However, in test suite " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4012 |
<< this_test_info->test_suite_name() << ",\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4013 |
<< "you defined test " << first_test_name << " and test " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4014 |
<< this_test_name << "\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4015 |
<< "using two different test fixture classes. This can happen if\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4016 |
<< "the two classes are from different namespaces or translation\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4017 |
<< "units and have the same name. You should probably rename one\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4018 |
<< "of the classes to put the tests into different test suites."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4019 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4020 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4021 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4022 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4023 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4024 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4025 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4026 |
#if GTEST_HAS_SEH |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4027 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4028 |
// Adds an "exception thrown" fatal failure to the current test. This |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4029 |
// function returns its result via an output parameter pointer because VC++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4030 |
// prohibits creation of objects with destructors on stack in functions |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4031 |
// using __try (see error C2712). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4032 |
static std::string* FormatSehExceptionMessage(DWORD exception_code, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4033 |
const char* location) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4034 |
Message message; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4035 |
message << "SEH exception with code 0x" << std::setbase(16) << |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4036 |
exception_code << std::setbase(10) << " thrown in " << location << "."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4037 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4038 |
return new std::string(message.GetString()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4039 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4040 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4041 |
#endif // GTEST_HAS_SEH |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4042 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4043 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4044 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4045 |
#if GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4046 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4047 |
// Adds an "exception thrown" fatal failure to the current test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4048 |
static std::string FormatCxxExceptionMessage(const char* description, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4049 |
const char* location) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4050 |
Message message; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4051 |
if (description != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4052 |
message << "C++ exception with description \"" << description << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4053 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4054 |
message << "Unknown C++ exception"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4055 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4056 |
message << " thrown in " << location << "."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4057 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4058 |
return message.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4059 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4060 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4061 |
static std::string PrintTestPartResultToString( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4062 |
const TestPartResult& test_part_result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4063 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4064 |
GoogleTestFailureException::GoogleTestFailureException( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4065 |
const TestPartResult& failure) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4066 |
: ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4067 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4068 |
#endif // GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4069 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4070 |
// We put these helper functions in the internal namespace as IBM's xlC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4071 |
// compiler rejects the code if they were declared static. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4072 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4073 |
// Runs the given method and handles SEH exceptions it throws, when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4074 |
// SEH is supported; returns the 0-value for type Result in case of an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4075 |
// SEH exception. (Microsoft compilers cannot handle SEH and C++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4076 |
// exceptions in the same function. Therefore, we provide a separate |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4077 |
// wrapper function for handling SEH exceptions.) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4078 |
template <class T, typename Result> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4079 |
Result HandleSehExceptionsInMethodIfSupported( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4080 |
T* object, Result (T::*method)(), const char* location) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4081 |
#if GTEST_HAS_SEH |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4082 |
__try { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4083 |
return (object->*method)(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4084 |
} __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4085 |
GetExceptionCode())) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4086 |
// We create the exception message on the heap because VC++ prohibits |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4087 |
// creation of objects with destructors on stack in functions using __try |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4088 |
// (see error C2712). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4089 |
std::string* exception_message = FormatSehExceptionMessage( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4090 |
GetExceptionCode(), location); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4091 |
internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4092 |
*exception_message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4093 |
delete exception_message; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4094 |
return static_cast<Result>(0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4095 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4096 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4097 |
(void)location; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4098 |
return (object->*method)(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4099 |
#endif // GTEST_HAS_SEH |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4100 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4101 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4102 |
// Runs the given method and catches and reports C++ and/or SEH-style |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4103 |
// exceptions, if they are supported; returns the 0-value for type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4104 |
// Result in case of an SEH exception. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4105 |
template <class T, typename Result> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4106 |
Result HandleExceptionsInMethodIfSupported( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4107 |
T* object, Result (T::*method)(), const char* location) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4108 |
// NOTE: The user code can affect the way in which Google Test handles |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4109 |
// exceptions by setting GTEST_FLAG(catch_exceptions), but only before |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4110 |
// RUN_ALL_TESTS() starts. It is technically possible to check the flag |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4111 |
// after the exception is caught and either report or re-throw the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4112 |
// exception based on the flag's value: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4113 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4114 |
// try { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4115 |
// // Perform the test method. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4116 |
// } catch (...) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4117 |
// if (GTEST_FLAG(catch_exceptions)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4118 |
// // Report the exception as failure. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4119 |
// else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4120 |
// throw; // Re-throws the original exception. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4121 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4122 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4123 |
// However, the purpose of this flag is to allow the program to drop into |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4124 |
// the debugger when the exception is thrown. On most platforms, once the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4125 |
// control enters the catch block, the exception origin information is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4126 |
// lost and the debugger will stop the program at the point of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4127 |
// re-throw in this function -- instead of at the point of the original |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4128 |
// throw statement in the code under test. For this reason, we perform |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4129 |
// the check early, sacrificing the ability to affect Google Test's |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4130 |
// exception handling in the method where the exception is thrown. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4131 |
if (internal::GetUnitTestImpl()->catch_exceptions()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4132 |
#if GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4133 |
try { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4134 |
return HandleSehExceptionsInMethodIfSupported(object, method, location); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4135 |
} catch (const AssertionException&) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4136 |
// This failure was reported already. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4137 |
} catch (const internal::GoogleTestFailureException&) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4138 |
// This exception type can only be thrown by a failed Google |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4139 |
// Test assertion with the intention of letting another testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4140 |
// framework catch it. Therefore we just re-throw it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4141 |
throw; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4142 |
} catch (const std::exception& e) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4143 |
internal::ReportFailureInUnknownLocation( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4144 |
TestPartResult::kFatalFailure, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4145 |
FormatCxxExceptionMessage(e.what(), location)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4146 |
} catch (...) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4147 |
internal::ReportFailureInUnknownLocation( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4148 |
TestPartResult::kFatalFailure, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4149 |
FormatCxxExceptionMessage(nullptr, location)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4150 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4151 |
return static_cast<Result>(0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4152 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4153 |
return HandleSehExceptionsInMethodIfSupported(object, method, location); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4154 |
#endif // GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4155 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4156 |
return (object->*method)(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4157 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4158 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4159 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4160 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4161 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4162 |
// Runs the test and updates the test result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4163 |
void Test::Run() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4164 |
if (!HasSameFixtureClass()) return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4165 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4166 |
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4167 |
impl->os_stack_trace_getter()->UponLeavingGTest(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4168 |
internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4169 |
// We will run the test only if SetUp() was successful and didn't call |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4170 |
// GTEST_SKIP(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4171 |
if (!HasFatalFailure() && !IsSkipped()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4172 |
impl->os_stack_trace_getter()->UponLeavingGTest(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4173 |
internal::HandleExceptionsInMethodIfSupported( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4174 |
this, &Test::TestBody, "the test body"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4175 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4176 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4177 |
// However, we want to clean up as much as possible. Hence we will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4178 |
// always call TearDown(), even if SetUp() or the test body has |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4179 |
// failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4180 |
impl->os_stack_trace_getter()->UponLeavingGTest(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4181 |
internal::HandleExceptionsInMethodIfSupported( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4182 |
this, &Test::TearDown, "TearDown()"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4183 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4184 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4185 |
// Returns true if and only if the current test has a fatal failure. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4186 |
bool Test::HasFatalFailure() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4187 |
return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4188 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4189 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4190 |
// Returns true if and only if the current test has a non-fatal failure. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4191 |
bool Test::HasNonfatalFailure() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4192 |
return internal::GetUnitTestImpl()->current_test_result()-> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4193 |
HasNonfatalFailure(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4194 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4195 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4196 |
// Returns true if and only if the current test was skipped. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4197 |
bool Test::IsSkipped() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4198 |
return internal::GetUnitTestImpl()->current_test_result()->Skipped(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4199 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4200 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4201 |
// class TestInfo |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4202 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4203 |
// Constructs a TestInfo object. It assumes ownership of the test factory |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4204 |
// object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4205 |
TestInfo::TestInfo(const std::string& a_test_suite_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4206 |
const std::string& a_name, const char* a_type_param, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4207 |
const char* a_value_param, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4208 |
internal::CodeLocation a_code_location, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4209 |
internal::TypeId fixture_class_id, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4210 |
internal::TestFactoryBase* factory) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4211 |
: test_suite_name_(a_test_suite_name), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4212 |
name_(a_name), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4213 |
type_param_(a_type_param ? new std::string(a_type_param) : nullptr), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4214 |
value_param_(a_value_param ? new std::string(a_value_param) : nullptr), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4215 |
location_(a_code_location), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4216 |
fixture_class_id_(fixture_class_id), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4217 |
should_run_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4218 |
is_disabled_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4219 |
matches_filter_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4220 |
is_in_another_shard_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4221 |
factory_(factory), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4222 |
result_() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4223 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4224 |
// Destructs a TestInfo object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4225 |
TestInfo::~TestInfo() { delete factory_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4226 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4227 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4228 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4229 |
// Creates a new TestInfo object and registers it with Google Test; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4230 |
// returns the created object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4231 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4232 |
// Arguments: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4233 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4234 |
// test_suite_name: name of the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4235 |
// name: name of the test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4236 |
// type_param: the name of the test's type parameter, or NULL if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4237 |
// this is not a typed or a type-parameterized test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4238 |
// value_param: text representation of the test's value parameter, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4239 |
// or NULL if this is not a value-parameterized test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4240 |
// code_location: code location where the test is defined |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4241 |
// fixture_class_id: ID of the test fixture class |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4242 |
// set_up_tc: pointer to the function that sets up the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4243 |
// tear_down_tc: pointer to the function that tears down the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4244 |
// factory: pointer to the factory that creates a test object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4245 |
// The newly created TestInfo instance will assume |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4246 |
// ownership of the factory object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4247 |
TestInfo* MakeAndRegisterTestInfo( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4248 |
const char* test_suite_name, const char* name, const char* type_param, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4249 |
const char* value_param, CodeLocation code_location, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4250 |
TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4251 |
TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4252 |
TestInfo* const test_info = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4253 |
new TestInfo(test_suite_name, name, type_param, value_param, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4254 |
code_location, fixture_class_id, factory); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4255 |
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4256 |
return test_info; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4257 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4258 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4259 |
void ReportInvalidTestSuiteType(const char* test_suite_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4260 |
CodeLocation code_location) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4261 |
Message errors; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4262 |
errors |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4263 |
<< "Attempted redefinition of test suite " << test_suite_name << ".\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4264 |
<< "All tests in the same test suite must use the same test fixture\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4265 |
<< "class. However, in test suite " << test_suite_name << ", you tried\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4266 |
<< "to define a test using a fixture class different from the one\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4267 |
<< "used earlier. This can happen if the two fixture classes are\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4268 |
<< "from different namespaces and have the same name. You should\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4269 |
<< "probably rename one of the classes to put the tests into different\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4270 |
<< "test suites."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4271 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4272 |
GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4273 |
code_location.line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4274 |
<< " " << errors.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4275 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4276 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4277 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4278 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4279 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4280 |
// A predicate that checks the test name of a TestInfo against a known |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4281 |
// value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4282 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4283 |
// This is used for implementation of the TestSuite class only. We put |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4284 |
// it in the anonymous namespace to prevent polluting the outer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4285 |
// namespace. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4286 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4287 |
// TestNameIs is copyable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4288 |
class TestNameIs { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4289 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4290 |
// Constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4291 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4292 |
// TestNameIs has NO default constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4293 |
explicit TestNameIs(const char* name) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4294 |
: name_(name) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4295 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4296 |
// Returns true if and only if the test name of test_info matches name_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4297 |
bool operator()(const TestInfo * test_info) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4298 |
return test_info && test_info->name() == name_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4299 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4300 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4301 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4302 |
std::string name_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4303 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4304 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4305 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4306 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4307 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4308 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4309 |
// This method expands all parameterized tests registered with macros TEST_P |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4310 |
// and INSTANTIATE_TEST_SUITE_P into regular tests and registers those. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4311 |
// This will be done just once during the program runtime. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4312 |
void UnitTestImpl::RegisterParameterizedTests() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4313 |
if (!parameterized_tests_registered_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4314 |
parameterized_test_registry_.RegisterTests(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4315 |
type_parameterized_test_registry_.CheckForInstantiations(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4316 |
parameterized_tests_registered_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4317 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4318 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4319 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4320 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4321 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4322 |
// Creates the test object, runs it, records its result, and then |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4323 |
// deletes it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4324 |
void TestInfo::Run() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4325 |
if (!should_run_) return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4326 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4327 |
// Tells UnitTest where to store test result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4328 |
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4329 |
impl->set_current_test_info(this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4330 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4331 |
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4332 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4333 |
// Notifies the unit test event listeners that a test is about to start. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4334 |
repeater->OnTestStart(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4335 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4336 |
result_.set_start_timestamp(internal::GetTimeInMillis()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4337 |
internal::Timer timer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4338 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4339 |
impl->os_stack_trace_getter()->UponLeavingGTest(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4340 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4341 |
// Creates the test object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4342 |
Test* const test = internal::HandleExceptionsInMethodIfSupported( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4343 |
factory_, &internal::TestFactoryBase::CreateTest, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4344 |
"the test fixture's constructor"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4345 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4346 |
// Runs the test if the constructor didn't generate a fatal failure or invoke |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4347 |
// GTEST_SKIP(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4348 |
// Note that the object will not be null |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4349 |
if (!Test::HasFatalFailure() && !Test::IsSkipped()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4350 |
// This doesn't throw as all user code that can throw are wrapped into |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4351 |
// exception handling code. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4352 |
test->Run(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4353 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4354 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4355 |
if (test != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4356 |
// Deletes the test object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4357 |
impl->os_stack_trace_getter()->UponLeavingGTest(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4358 |
internal::HandleExceptionsInMethodIfSupported( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4359 |
test, &Test::DeleteSelf_, "the test fixture's destructor"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4360 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4361 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4362 |
result_.set_elapsed_time(timer.Elapsed()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4363 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4364 |
// Notifies the unit test event listener that a test has just finished. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4365 |
repeater->OnTestEnd(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4366 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4367 |
// Tells UnitTest to stop associating assertion results to this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4368 |
// test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4369 |
impl->set_current_test_info(nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4370 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4371 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4372 |
// Skip and records a skipped test result for this object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4373 |
void TestInfo::Skip() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4374 |
if (!should_run_) return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4375 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4376 |
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4377 |
impl->set_current_test_info(this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4378 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4379 |
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4380 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4381 |
// Notifies the unit test event listeners that a test is about to start. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4382 |
repeater->OnTestStart(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4383 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4384 |
const TestPartResult test_part_result = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4385 |
TestPartResult(TestPartResult::kSkip, this->file(), this->line(), ""); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4386 |
impl->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4387 |
test_part_result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4388 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4389 |
// Notifies the unit test event listener that a test has just finished. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4390 |
repeater->OnTestEnd(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4391 |
impl->set_current_test_info(nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4392 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4393 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4394 |
// class TestSuite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4395 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4396 |
// Gets the number of successful tests in this test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4397 |
int TestSuite::successful_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4398 |
return CountIf(test_info_list_, TestPassed); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4399 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4400 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4401 |
// Gets the number of successful tests in this test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4402 |
int TestSuite::skipped_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4403 |
return CountIf(test_info_list_, TestSkipped); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4404 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4405 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4406 |
// Gets the number of failed tests in this test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4407 |
int TestSuite::failed_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4408 |
return CountIf(test_info_list_, TestFailed); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4409 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4410 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4411 |
// Gets the number of disabled tests that will be reported in the XML report. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4412 |
int TestSuite::reportable_disabled_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4413 |
return CountIf(test_info_list_, TestReportableDisabled); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4414 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4415 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4416 |
// Gets the number of disabled tests in this test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4417 |
int TestSuite::disabled_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4418 |
return CountIf(test_info_list_, TestDisabled); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4419 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4420 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4421 |
// Gets the number of tests to be printed in the XML report. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4422 |
int TestSuite::reportable_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4423 |
return CountIf(test_info_list_, TestReportable); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4424 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4425 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4426 |
// Get the number of tests in this test suite that should run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4427 |
int TestSuite::test_to_run_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4428 |
return CountIf(test_info_list_, ShouldRunTest); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4429 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4430 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4431 |
// Gets the number of all tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4432 |
int TestSuite::total_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4433 |
return static_cast<int>(test_info_list_.size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4434 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4435 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4436 |
// Creates a TestSuite with the given name. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4437 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4438 |
// Arguments: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4439 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4440 |
// a_name: name of the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4441 |
// a_type_param: the name of the test suite's type parameter, or NULL if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4442 |
// this is not a typed or a type-parameterized test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4443 |
// set_up_tc: pointer to the function that sets up the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4444 |
// tear_down_tc: pointer to the function that tears down the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4445 |
TestSuite::TestSuite(const char* a_name, const char* a_type_param, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4446 |
internal::SetUpTestSuiteFunc set_up_tc, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4447 |
internal::TearDownTestSuiteFunc tear_down_tc) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4448 |
: name_(a_name), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4449 |
type_param_(a_type_param ? new std::string(a_type_param) : nullptr), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4450 |
set_up_tc_(set_up_tc), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4451 |
tear_down_tc_(tear_down_tc), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4452 |
should_run_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4453 |
start_timestamp_(0), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4454 |
elapsed_time_(0) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4455 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4456 |
// Destructor of TestSuite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4457 |
TestSuite::~TestSuite() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4458 |
// Deletes every Test in the collection. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4459 |
ForEach(test_info_list_, internal::Delete<TestInfo>); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4460 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4461 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4462 |
// Returns the i-th test among all the tests. i can range from 0 to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4463 |
// total_test_count() - 1. If i is not in that range, returns NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4464 |
const TestInfo* TestSuite::GetTestInfo(int i) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4465 |
const int index = GetElementOr(test_indices_, i, -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4466 |
return index < 0 ? nullptr : test_info_list_[static_cast<size_t>(index)]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4467 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4468 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4469 |
// Returns the i-th test among all the tests. i can range from 0 to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4470 |
// total_test_count() - 1. If i is not in that range, returns NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4471 |
TestInfo* TestSuite::GetMutableTestInfo(int i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4472 |
const int index = GetElementOr(test_indices_, i, -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4473 |
return index < 0 ? nullptr : test_info_list_[static_cast<size_t>(index)]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4474 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4475 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4476 |
// Adds a test to this test suite. Will delete the test upon |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4477 |
// destruction of the TestSuite object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4478 |
void TestSuite::AddTestInfo(TestInfo* test_info) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4479 |
test_info_list_.push_back(test_info); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4480 |
test_indices_.push_back(static_cast<int>(test_indices_.size())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4481 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4482 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4483 |
// Runs every test in this TestSuite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4484 |
void TestSuite::Run() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4485 |
if (!should_run_) return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4486 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4487 |
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4488 |
impl->set_current_test_suite(this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4489 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4490 |
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4491 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4492 |
// Call both legacy and the new API |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4493 |
repeater->OnTestSuiteStart(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4494 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4495 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4496 |
repeater->OnTestCaseStart(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4497 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4498 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4499 |
impl->os_stack_trace_getter()->UponLeavingGTest(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4500 |
internal::HandleExceptionsInMethodIfSupported( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4501 |
this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4502 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4503 |
start_timestamp_ = internal::GetTimeInMillis(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4504 |
internal::Timer timer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4505 |
for (int i = 0; i < total_test_count(); i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4506 |
GetMutableTestInfo(i)->Run(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4507 |
if (GTEST_FLAG(fail_fast) && GetMutableTestInfo(i)->result()->Failed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4508 |
for (int j = i + 1; j < total_test_count(); j++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4509 |
GetMutableTestInfo(j)->Skip(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4510 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4511 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4512 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4513 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4514 |
elapsed_time_ = timer.Elapsed(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4515 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4516 |
impl->os_stack_trace_getter()->UponLeavingGTest(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4517 |
internal::HandleExceptionsInMethodIfSupported( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4518 |
this, &TestSuite::RunTearDownTestSuite, "TearDownTestSuite()"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4519 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4520 |
// Call both legacy and the new API |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4521 |
repeater->OnTestSuiteEnd(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4522 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4523 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4524 |
repeater->OnTestCaseEnd(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4525 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4526 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4527 |
impl->set_current_test_suite(nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4528 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4529 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4530 |
// Skips all tests under this TestSuite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4531 |
void TestSuite::Skip() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4532 |
if (!should_run_) return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4533 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4534 |
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4535 |
impl->set_current_test_suite(this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4536 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4537 |
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4538 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4539 |
// Call both legacy and the new API |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4540 |
repeater->OnTestSuiteStart(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4541 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4542 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4543 |
repeater->OnTestCaseStart(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4544 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4545 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4546 |
for (int i = 0; i < total_test_count(); i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4547 |
GetMutableTestInfo(i)->Skip(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4548 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4549 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4550 |
// Call both legacy and the new API |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4551 |
repeater->OnTestSuiteEnd(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4552 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4553 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4554 |
repeater->OnTestCaseEnd(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4555 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4556 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4557 |
impl->set_current_test_suite(nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4558 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4559 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4560 |
// Clears the results of all tests in this test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4561 |
void TestSuite::ClearResult() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4562 |
ad_hoc_test_result_.Clear(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4563 |
ForEach(test_info_list_, TestInfo::ClearTestResult); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4564 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4565 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4566 |
// Shuffles the tests in this test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4567 |
void TestSuite::ShuffleTests(internal::Random* random) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4568 |
Shuffle(random, &test_indices_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4569 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4570 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4571 |
// Restores the test order to before the first shuffle. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4572 |
void TestSuite::UnshuffleTests() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4573 |
for (size_t i = 0; i < test_indices_.size(); i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4574 |
test_indices_[i] = static_cast<int>(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4575 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4576 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4577 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4578 |
// Formats a countable noun. Depending on its quantity, either the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4579 |
// singular form or the plural form is used. e.g. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4580 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4581 |
// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4582 |
// FormatCountableNoun(5, "book", "books") returns "5 books". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4583 |
static std::string FormatCountableNoun(int count, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4584 |
const char * singular_form, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4585 |
const char * plural_form) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4586 |
return internal::StreamableToString(count) + " " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4587 |
(count == 1 ? singular_form : plural_form); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4588 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4589 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4590 |
// Formats the count of tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4591 |
static std::string FormatTestCount(int test_count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4592 |
return FormatCountableNoun(test_count, "test", "tests"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4593 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4594 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4595 |
// Formats the count of test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4596 |
static std::string FormatTestSuiteCount(int test_suite_count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4597 |
return FormatCountableNoun(test_suite_count, "test suite", "test suites"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4598 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4599 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4600 |
// Converts a TestPartResult::Type enum to human-friendly string |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4601 |
// representation. Both kNonFatalFailure and kFatalFailure are translated |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4602 |
// to "Failure", as the user usually doesn't care about the difference |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4603 |
// between the two when viewing the test result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4604 |
static const char * TestPartResultTypeToString(TestPartResult::Type type) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4605 |
switch (type) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4606 |
case TestPartResult::kSkip: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4607 |
return "Skipped\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4608 |
case TestPartResult::kSuccess: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4609 |
return "Success"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4610 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4611 |
case TestPartResult::kNonFatalFailure: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4612 |
case TestPartResult::kFatalFailure: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4613 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4614 |
return "error: "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4615 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4616 |
return "Failure\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4617 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4618 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4619 |
return "Unknown result type"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4620 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4621 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4622 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4623 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4624 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4625 |
enum class GTestColor { kDefault, kRed, kGreen, kYellow }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4626 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4627 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4628 |
// Prints a TestPartResult to an std::string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4629 |
static std::string PrintTestPartResultToString( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4630 |
const TestPartResult& test_part_result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4631 |
return (Message() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4632 |
<< internal::FormatFileLocation(test_part_result.file_name(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4633 |
test_part_result.line_number()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4634 |
<< " " << TestPartResultTypeToString(test_part_result.type()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4635 |
<< test_part_result.message()).GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4636 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4637 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4638 |
// Prints a TestPartResult. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4639 |
static void PrintTestPartResult(const TestPartResult& test_part_result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4640 |
const std::string& result = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4641 |
PrintTestPartResultToString(test_part_result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4642 |
printf("%s\n", result.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4643 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4644 |
// If the test program runs in Visual Studio or a debugger, the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4645 |
// following statements add the test part result message to the Output |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4646 |
// window such that the user can double-click on it to jump to the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4647 |
// corresponding source code location; otherwise they do nothing. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4648 |
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4649 |
// We don't call OutputDebugString*() on Windows Mobile, as printing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4650 |
// to stdout is done by OutputDebugString() there already - we don't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4651 |
// want the same message printed twice. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4652 |
::OutputDebugStringA(result.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4653 |
::OutputDebugStringA("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4654 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4655 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4656 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4657 |
// class PrettyUnitTestResultPrinter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4658 |
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4659 |
!GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4660 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4661 |
// Returns the character attribute for the given color. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4662 |
static WORD GetColorAttribute(GTestColor color) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4663 |
switch (color) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4664 |
case GTestColor::kRed: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4665 |
return FOREGROUND_RED; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4666 |
case GTestColor::kGreen: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4667 |
return FOREGROUND_GREEN; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4668 |
case GTestColor::kYellow: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4669 |
return FOREGROUND_RED | FOREGROUND_GREEN; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4670 |
default: return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4671 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4672 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4673 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4674 |
static int GetBitOffset(WORD color_mask) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4675 |
if (color_mask == 0) return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4676 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4677 |
int bitOffset = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4678 |
while ((color_mask & 1) == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4679 |
color_mask >>= 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4680 |
++bitOffset; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4681 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4682 |
return bitOffset; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4683 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4684 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4685 |
static WORD GetNewColor(GTestColor color, WORD old_color_attrs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4686 |
// Let's reuse the BG |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4687 |
static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN | |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4688 |
BACKGROUND_RED | BACKGROUND_INTENSITY; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4689 |
static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN | |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4690 |
FOREGROUND_RED | FOREGROUND_INTENSITY; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4691 |
const WORD existing_bg = old_color_attrs & background_mask; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4692 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4693 |
WORD new_color = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4694 |
GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4695 |
static const int bg_bitOffset = GetBitOffset(background_mask); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4696 |
static const int fg_bitOffset = GetBitOffset(foreground_mask); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4697 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4698 |
if (((new_color & background_mask) >> bg_bitOffset) == |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4699 |
((new_color & foreground_mask) >> fg_bitOffset)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4700 |
new_color ^= FOREGROUND_INTENSITY; // invert intensity |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4701 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4702 |
return new_color; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4703 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4704 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4705 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4706 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4707 |
// Returns the ANSI color code for the given color. GTestColor::kDefault is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4708 |
// an invalid input. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4709 |
static const char* GetAnsiColorCode(GTestColor color) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4710 |
switch (color) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4711 |
case GTestColor::kRed: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4712 |
return "1"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4713 |
case GTestColor::kGreen: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4714 |
return "2"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4715 |
case GTestColor::kYellow: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4716 |
return "3"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4717 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4718 |
return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4719 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4720 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4721 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4722 |
#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4723 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4724 |
// Returns true if and only if Google Test should use colors in the output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4725 |
bool ShouldUseColor(bool stdout_is_tty) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4726 |
const char* const gtest_color = GTEST_FLAG(color).c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4727 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4728 |
if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4729 |
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4730 |
// On Windows the TERM variable is usually not set, but the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4731 |
// console there does support colors. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4732 |
return stdout_is_tty; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4733 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4734 |
// On non-Windows platforms, we rely on the TERM variable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4735 |
const char* const term = posix::GetEnv("TERM"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4736 |
const bool term_supports_color = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4737 |
String::CStringEquals(term, "xterm") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4738 |
String::CStringEquals(term, "xterm-color") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4739 |
String::CStringEquals(term, "xterm-256color") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4740 |
String::CStringEquals(term, "screen") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4741 |
String::CStringEquals(term, "screen-256color") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4742 |
String::CStringEquals(term, "tmux") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4743 |
String::CStringEquals(term, "tmux-256color") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4744 |
String::CStringEquals(term, "rxvt-unicode") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4745 |
String::CStringEquals(term, "rxvt-unicode-256color") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4746 |
String::CStringEquals(term, "linux") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4747 |
String::CStringEquals(term, "cygwin"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4748 |
return stdout_is_tty && term_supports_color; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4749 |
#endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4750 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4751 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4752 |
return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4753 |
String::CaseInsensitiveCStringEquals(gtest_color, "true") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4754 |
String::CaseInsensitiveCStringEquals(gtest_color, "t") || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4755 |
String::CStringEquals(gtest_color, "1"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4756 |
// We take "yes", "true", "t", and "1" as meaning "yes". If the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4757 |
// value is neither one of these nor "auto", we treat it as "no" to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4758 |
// be conservative. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4759 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4760 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4761 |
// Helpers for printing colored strings to stdout. Note that on Windows, we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4762 |
// cannot simply emit special characters and have the terminal change colors. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4763 |
// This routine must actually emit the characters rather than return a string |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4764 |
// that would be colored when printed, as can be done on Linux. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4765 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4766 |
GTEST_ATTRIBUTE_PRINTF_(2, 3) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4767 |
static void ColoredPrintf(GTestColor color, const char *fmt, ...) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4768 |
va_list args; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4769 |
va_start(args, fmt); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4770 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4771 |
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4772 |
GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4773 |
const bool use_color = AlwaysFalse(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4774 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4775 |
static const bool in_color_mode = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4776 |
ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4777 |
const bool use_color = in_color_mode && (color != GTestColor::kDefault); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4778 |
#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4779 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4780 |
if (!use_color) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4781 |
vprintf(fmt, args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4782 |
va_end(args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4783 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4784 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4785 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4786 |
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4787 |
!GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4788 |
const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4789 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4790 |
// Gets the current text color. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4791 |
CONSOLE_SCREEN_BUFFER_INFO buffer_info; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4792 |
GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4793 |
const WORD old_color_attrs = buffer_info.wAttributes; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4794 |
const WORD new_color = GetNewColor(color, old_color_attrs); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4795 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4796 |
// We need to flush the stream buffers into the console before each |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4797 |
// SetConsoleTextAttribute call lest it affect the text that is already |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4798 |
// printed but has not yet reached the console. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4799 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4800 |
SetConsoleTextAttribute(stdout_handle, new_color); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4801 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4802 |
vprintf(fmt, args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4803 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4804 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4805 |
// Restores the text color. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4806 |
SetConsoleTextAttribute(stdout_handle, old_color_attrs); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4807 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4808 |
printf("\033[0;3%sm", GetAnsiColorCode(color)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4809 |
vprintf(fmt, args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4810 |
printf("\033[m"); // Resets the terminal to default. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4811 |
#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4812 |
va_end(args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4813 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4814 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4815 |
// Text printed in Google Test's text output and --gtest_list_tests |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4816 |
// output to label the type parameter and value parameter for a test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4817 |
static const char kTypeParamLabel[] = "TypeParam"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4818 |
static const char kValueParamLabel[] = "GetParam()"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4819 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4820 |
static void PrintFullTestCommentIfPresent(const TestInfo& test_info) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4821 |
const char* const type_param = test_info.type_param(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4822 |
const char* const value_param = test_info.value_param(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4823 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4824 |
if (type_param != nullptr || value_param != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4825 |
printf(", where "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4826 |
if (type_param != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4827 |
printf("%s = %s", kTypeParamLabel, type_param); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4828 |
if (value_param != nullptr) printf(" and "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4829 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4830 |
if (value_param != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4831 |
printf("%s = %s", kValueParamLabel, value_param); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4832 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4833 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4834 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4835 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4836 |
// This class implements the TestEventListener interface. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4837 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4838 |
// Class PrettyUnitTestResultPrinter is copyable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4839 |
class PrettyUnitTestResultPrinter : public TestEventListener { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4840 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4841 |
PrettyUnitTestResultPrinter() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4842 |
static void PrintTestName(const char* test_suite, const char* test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4843 |
printf("%s.%s", test_suite, test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4844 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4845 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4846 |
// The following methods override what's in the TestEventListener class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4847 |
void OnTestProgramStart(const UnitTest& /*unit_test*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4848 |
void OnTestIterationStart(const UnitTest& unit_test, int iteration) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4849 |
void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4850 |
void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4851 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4852 |
void OnTestCaseStart(const TestCase& test_case) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4853 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4854 |
void OnTestSuiteStart(const TestSuite& test_suite) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4855 |
#endif // OnTestCaseStart |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4856 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4857 |
void OnTestStart(const TestInfo& test_info) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4858 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4859 |
void OnTestPartResult(const TestPartResult& result) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4860 |
void OnTestEnd(const TestInfo& test_info) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4861 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4862 |
void OnTestCaseEnd(const TestCase& test_case) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4863 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4864 |
void OnTestSuiteEnd(const TestSuite& test_suite) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4865 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4866 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4867 |
void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4868 |
void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4869 |
void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4870 |
void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4871 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4872 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4873 |
static void PrintFailedTests(const UnitTest& unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4874 |
static void PrintFailedTestSuites(const UnitTest& unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4875 |
static void PrintSkippedTests(const UnitTest& unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4876 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4877 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4878 |
// Fired before each iteration of tests starts. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4879 |
void PrettyUnitTestResultPrinter::OnTestIterationStart( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4880 |
const UnitTest& unit_test, int iteration) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4881 |
if (GTEST_FLAG(repeat) != 1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4882 |
printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4883 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4884 |
const char* const filter = GTEST_FLAG(filter).c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4885 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4886 |
// Prints the filter if it's not *. This reminds the user that some |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4887 |
// tests may be skipped. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4888 |
if (!String::CStringEquals(filter, kUniversalFilter)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4889 |
ColoredPrintf(GTestColor::kYellow, "Note: %s filter = %s\n", GTEST_NAME_, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4890 |
filter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4891 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4892 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4893 |
if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4894 |
const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4895 |
ColoredPrintf(GTestColor::kYellow, "Note: This is test shard %d of %s.\n", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4896 |
static_cast<int>(shard_index) + 1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4897 |
internal::posix::GetEnv(kTestTotalShards)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4898 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4899 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4900 |
if (GTEST_FLAG(shuffle)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4901 |
ColoredPrintf(GTestColor::kYellow, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4902 |
"Note: Randomizing tests' orders with a seed of %d .\n", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4903 |
unit_test.random_seed()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4904 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4905 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4906 |
ColoredPrintf(GTestColor::kGreen, "[==========] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4907 |
printf("Running %s from %s.\n", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4908 |
FormatTestCount(unit_test.test_to_run_count()).c_str(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4909 |
FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4910 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4911 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4912 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4913 |
void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4914 |
const UnitTest& /*unit_test*/) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4915 |
ColoredPrintf(GTestColor::kGreen, "[----------] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4916 |
printf("Global test environment set-up.\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4917 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4918 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4919 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4920 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4921 |
void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4922 |
const std::string counts = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4923 |
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4924 |
ColoredPrintf(GTestColor::kGreen, "[----------] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4925 |
printf("%s from %s", counts.c_str(), test_case.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4926 |
if (test_case.type_param() == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4927 |
printf("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4928 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4929 |
printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4930 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4931 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4932 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4933 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4934 |
void PrettyUnitTestResultPrinter::OnTestSuiteStart( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4935 |
const TestSuite& test_suite) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4936 |
const std::string counts = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4937 |
FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4938 |
ColoredPrintf(GTestColor::kGreen, "[----------] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4939 |
printf("%s from %s", counts.c_str(), test_suite.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4940 |
if (test_suite.type_param() == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4941 |
printf("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4942 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4943 |
printf(", where %s = %s\n", kTypeParamLabel, test_suite.type_param()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4944 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4945 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4946 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4947 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4948 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4949 |
void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4950 |
ColoredPrintf(GTestColor::kGreen, "[ RUN ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4951 |
PrintTestName(test_info.test_suite_name(), test_info.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4952 |
printf("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4953 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4954 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4955 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4956 |
// Called after an assertion failure. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4957 |
void PrettyUnitTestResultPrinter::OnTestPartResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4958 |
const TestPartResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4959 |
switch (result.type()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4960 |
// If the test part succeeded, we don't need to do anything. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4961 |
case TestPartResult::kSuccess: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4962 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4963 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4964 |
// Print failure message from the assertion |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4965 |
// (e.g. expected this and got that). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4966 |
PrintTestPartResult(result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4967 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4968 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4969 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4970 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4971 |
void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4972 |
if (test_info.result()->Passed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4973 |
ColoredPrintf(GTestColor::kGreen, "[ OK ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4974 |
} else if (test_info.result()->Skipped()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4975 |
ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4976 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4977 |
ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4978 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4979 |
PrintTestName(test_info.test_suite_name(), test_info.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4980 |
if (test_info.result()->Failed()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4981 |
PrintFullTestCommentIfPresent(test_info); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4982 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4983 |
if (GTEST_FLAG(print_time)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4984 |
printf(" (%s ms)\n", internal::StreamableToString( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4985 |
test_info.result()->elapsed_time()).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4986 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4987 |
printf("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4988 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4989 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4990 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4991 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4992 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4993 |
void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4994 |
if (!GTEST_FLAG(print_time)) return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4995 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4996 |
const std::string counts = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4997 |
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4998 |
ColoredPrintf(GTestColor::kGreen, "[----------] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4999 |
printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5000 |
internal::StreamableToString(test_case.elapsed_time()).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5001 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5002 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5003 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5004 |
void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5005 |
if (!GTEST_FLAG(print_time)) return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5006 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5007 |
const std::string counts = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5008 |
FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5009 |
ColoredPrintf(GTestColor::kGreen, "[----------] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5010 |
printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_suite.name(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5011 |
internal::StreamableToString(test_suite.elapsed_time()).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5012 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5013 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5014 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5015 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5016 |
void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5017 |
const UnitTest& /*unit_test*/) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5018 |
ColoredPrintf(GTestColor::kGreen, "[----------] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5019 |
printf("Global test environment tear-down\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5020 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5021 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5022 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5023 |
// Internal helper for printing the list of failed tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5024 |
void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5025 |
const int failed_test_count = unit_test.failed_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5026 |
ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5027 |
printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5028 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5029 |
for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5030 |
const TestSuite& test_suite = *unit_test.GetTestSuite(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5031 |
if (!test_suite.should_run() || (test_suite.failed_test_count() == 0)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5032 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5033 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5034 |
for (int j = 0; j < test_suite.total_test_count(); ++j) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5035 |
const TestInfo& test_info = *test_suite.GetTestInfo(j); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5036 |
if (!test_info.should_run() || !test_info.result()->Failed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5037 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5038 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5039 |
ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5040 |
printf("%s.%s", test_suite.name(), test_info.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5041 |
PrintFullTestCommentIfPresent(test_info); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5042 |
printf("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5043 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5044 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5045 |
printf("\n%2d FAILED %s\n", failed_test_count, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5046 |
failed_test_count == 1 ? "TEST" : "TESTS"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5047 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5048 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5049 |
// Internal helper for printing the list of test suite failures not covered by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5050 |
// PrintFailedTests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5051 |
void PrettyUnitTestResultPrinter::PrintFailedTestSuites( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5052 |
const UnitTest& unit_test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5053 |
int suite_failure_count = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5054 |
for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5055 |
const TestSuite& test_suite = *unit_test.GetTestSuite(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5056 |
if (!test_suite.should_run()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5057 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5058 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5059 |
if (test_suite.ad_hoc_test_result().Failed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5060 |
ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5061 |
printf("%s: SetUpTestSuite or TearDownTestSuite\n", test_suite.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5062 |
++suite_failure_count; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5063 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5064 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5065 |
if (suite_failure_count > 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5066 |
printf("\n%2d FAILED TEST %s\n", suite_failure_count, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5067 |
suite_failure_count == 1 ? "SUITE" : "SUITES"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5068 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5069 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5070 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5071 |
// Internal helper for printing the list of skipped tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5072 |
void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5073 |
const int skipped_test_count = unit_test.skipped_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5074 |
if (skipped_test_count == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5075 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5076 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5077 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5078 |
for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5079 |
const TestSuite& test_suite = *unit_test.GetTestSuite(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5080 |
if (!test_suite.should_run() || (test_suite.skipped_test_count() == 0)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5081 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5082 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5083 |
for (int j = 0; j < test_suite.total_test_count(); ++j) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5084 |
const TestInfo& test_info = *test_suite.GetTestInfo(j); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5085 |
if (!test_info.should_run() || !test_info.result()->Skipped()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5086 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5087 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5088 |
ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5089 |
printf("%s.%s", test_suite.name(), test_info.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5090 |
printf("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5091 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5092 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5093 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5094 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5095 |
void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5096 |
int /*iteration*/) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5097 |
ColoredPrintf(GTestColor::kGreen, "[==========] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5098 |
printf("%s from %s ran.", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5099 |
FormatTestCount(unit_test.test_to_run_count()).c_str(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5100 |
FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5101 |
if (GTEST_FLAG(print_time)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5102 |
printf(" (%s ms total)", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5103 |
internal::StreamableToString(unit_test.elapsed_time()).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5104 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5105 |
printf("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5106 |
ColoredPrintf(GTestColor::kGreen, "[ PASSED ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5107 |
printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5108 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5109 |
const int skipped_test_count = unit_test.skipped_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5110 |
if (skipped_test_count > 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5111 |
ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5112 |
printf("%s, listed below:\n", FormatTestCount(skipped_test_count).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5113 |
PrintSkippedTests(unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5114 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5115 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5116 |
if (!unit_test.Passed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5117 |
PrintFailedTests(unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5118 |
PrintFailedTestSuites(unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5119 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5120 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5121 |
int num_disabled = unit_test.reportable_disabled_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5122 |
if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5123 |
if (unit_test.Passed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5124 |
printf("\n"); // Add a spacer if no FAILURE banner is displayed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5125 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5126 |
ColoredPrintf(GTestColor::kYellow, " YOU HAVE %d DISABLED %s\n\n", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5127 |
num_disabled, num_disabled == 1 ? "TEST" : "TESTS"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5128 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5129 |
// Ensure that Google Test output is printed before, e.g., heapchecker output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5130 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5131 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5132 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5133 |
// End PrettyUnitTestResultPrinter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5134 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5135 |
// This class implements the TestEventListener interface. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5136 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5137 |
// Class BriefUnitTestResultPrinter is copyable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5138 |
class BriefUnitTestResultPrinter : public TestEventListener { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5139 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5140 |
BriefUnitTestResultPrinter() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5141 |
static void PrintTestName(const char* test_suite, const char* test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5142 |
printf("%s.%s", test_suite, test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5143 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5144 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5145 |
// The following methods override what's in the TestEventListener class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5146 |
void OnTestProgramStart(const UnitTest& /*unit_test*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5147 |
void OnTestIterationStart(const UnitTest& /*unit_test*/, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5148 |
int /*iteration*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5149 |
void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5150 |
void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5151 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5152 |
void OnTestCaseStart(const TestCase& /*test_case*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5153 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5154 |
void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5155 |
#endif // OnTestCaseStart |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5156 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5157 |
void OnTestStart(const TestInfo& /*test_info*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5158 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5159 |
void OnTestPartResult(const TestPartResult& result) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5160 |
void OnTestEnd(const TestInfo& test_info) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5161 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5162 |
void OnTestCaseEnd(const TestCase& /*test_case*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5163 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5164 |
void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5165 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5166 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5167 |
void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5168 |
void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5169 |
void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5170 |
void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5171 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5172 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5173 |
// Called after an assertion failure. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5174 |
void BriefUnitTestResultPrinter::OnTestPartResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5175 |
const TestPartResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5176 |
switch (result.type()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5177 |
// If the test part succeeded, we don't need to do anything. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5178 |
case TestPartResult::kSuccess: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5179 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5180 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5181 |
// Print failure message from the assertion |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5182 |
// (e.g. expected this and got that). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5183 |
PrintTestPartResult(result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5184 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5185 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5186 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5187 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5188 |
void BriefUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5189 |
if (test_info.result()->Failed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5190 |
ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5191 |
PrintTestName(test_info.test_suite_name(), test_info.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5192 |
PrintFullTestCommentIfPresent(test_info); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5193 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5194 |
if (GTEST_FLAG(print_time)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5195 |
printf(" (%s ms)\n", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5196 |
internal::StreamableToString(test_info.result()->elapsed_time()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5197 |
.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5198 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5199 |
printf("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5200 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5201 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5202 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5203 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5204 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5205 |
void BriefUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5206 |
int /*iteration*/) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5207 |
ColoredPrintf(GTestColor::kGreen, "[==========] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5208 |
printf("%s from %s ran.", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5209 |
FormatTestCount(unit_test.test_to_run_count()).c_str(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5210 |
FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5211 |
if (GTEST_FLAG(print_time)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5212 |
printf(" (%s ms total)", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5213 |
internal::StreamableToString(unit_test.elapsed_time()).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5214 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5215 |
printf("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5216 |
ColoredPrintf(GTestColor::kGreen, "[ PASSED ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5217 |
printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5218 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5219 |
const int skipped_test_count = unit_test.skipped_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5220 |
if (skipped_test_count > 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5221 |
ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5222 |
printf("%s.\n", FormatTestCount(skipped_test_count).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5223 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5224 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5225 |
int num_disabled = unit_test.reportable_disabled_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5226 |
if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5227 |
if (unit_test.Passed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5228 |
printf("\n"); // Add a spacer if no FAILURE banner is displayed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5229 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5230 |
ColoredPrintf(GTestColor::kYellow, " YOU HAVE %d DISABLED %s\n\n", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5231 |
num_disabled, num_disabled == 1 ? "TEST" : "TESTS"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5232 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5233 |
// Ensure that Google Test output is printed before, e.g., heapchecker output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5234 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5235 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5236 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5237 |
// End BriefUnitTestResultPrinter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5238 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5239 |
// class TestEventRepeater |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5240 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5241 |
// This class forwards events to other event listeners. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5242 |
class TestEventRepeater : public TestEventListener { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5243 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5244 |
TestEventRepeater() : forwarding_enabled_(true) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5245 |
~TestEventRepeater() override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5246 |
void Append(TestEventListener *listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5247 |
TestEventListener* Release(TestEventListener* listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5248 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5249 |
// Controls whether events will be forwarded to listeners_. Set to false |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5250 |
// in death test child processes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5251 |
bool forwarding_enabled() const { return forwarding_enabled_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5252 |
void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5253 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5254 |
void OnTestProgramStart(const UnitTest& unit_test) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5255 |
void OnTestIterationStart(const UnitTest& unit_test, int iteration) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5256 |
void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5257 |
void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5258 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5259 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5260 |
void OnTestCaseStart(const TestSuite& parameter) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5261 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5262 |
void OnTestSuiteStart(const TestSuite& parameter) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5263 |
void OnTestStart(const TestInfo& test_info) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5264 |
void OnTestPartResult(const TestPartResult& result) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5265 |
void OnTestEnd(const TestInfo& test_info) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5266 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5267 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5268 |
void OnTestCaseEnd(const TestCase& parameter) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5269 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5270 |
void OnTestSuiteEnd(const TestSuite& parameter) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5271 |
void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5272 |
void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5273 |
void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5274 |
void OnTestProgramEnd(const UnitTest& unit_test) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5275 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5276 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5277 |
// Controls whether events will be forwarded to listeners_. Set to false |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5278 |
// in death test child processes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5279 |
bool forwarding_enabled_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5280 |
// The list of listeners that receive events. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5281 |
std::vector<TestEventListener*> listeners_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5282 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5283 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5284 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5285 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5286 |
TestEventRepeater::~TestEventRepeater() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5287 |
ForEach(listeners_, Delete<TestEventListener>); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5288 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5289 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5290 |
void TestEventRepeater::Append(TestEventListener *listener) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5291 |
listeners_.push_back(listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5292 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5293 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5294 |
TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5295 |
for (size_t i = 0; i < listeners_.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5296 |
if (listeners_[i] == listener) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5297 |
listeners_.erase(listeners_.begin() + static_cast<int>(i)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5298 |
return listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5299 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5300 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5301 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5302 |
return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5303 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5304 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5305 |
// Since most methods are very similar, use macros to reduce boilerplate. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5306 |
// This defines a member that forwards the call to all listeners. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5307 |
#define GTEST_REPEATER_METHOD_(Name, Type) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5308 |
void TestEventRepeater::Name(const Type& parameter) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5309 |
if (forwarding_enabled_) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5310 |
for (size_t i = 0; i < listeners_.size(); i++) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5311 |
listeners_[i]->Name(parameter); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5312 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5313 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5314 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5315 |
// This defines a member that forwards the call to all listeners in reverse |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5316 |
// order. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5317 |
#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5318 |
void TestEventRepeater::Name(const Type& parameter) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5319 |
if (forwarding_enabled_) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5320 |
for (size_t i = listeners_.size(); i != 0; i--) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5321 |
listeners_[i - 1]->Name(parameter); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5322 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5323 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5324 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5325 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5326 |
GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5327 |
GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5328 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5329 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5330 |
GTEST_REPEATER_METHOD_(OnTestCaseStart, TestSuite) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5331 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5332 |
GTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5333 |
GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5334 |
GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5335 |
GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5336 |
GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5337 |
GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5338 |
GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5339 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5340 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5341 |
GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestSuite) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5342 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5343 |
GTEST_REVERSE_REPEATER_METHOD_(OnTestSuiteEnd, TestSuite) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5344 |
GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5345 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5346 |
#undef GTEST_REPEATER_METHOD_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5347 |
#undef GTEST_REVERSE_REPEATER_METHOD_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5348 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5349 |
void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5350 |
int iteration) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5351 |
if (forwarding_enabled_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5352 |
for (size_t i = 0; i < listeners_.size(); i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5353 |
listeners_[i]->OnTestIterationStart(unit_test, iteration); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5354 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5355 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5356 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5357 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5358 |
void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5359 |
int iteration) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5360 |
if (forwarding_enabled_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5361 |
for (size_t i = listeners_.size(); i > 0; i--) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5362 |
listeners_[i - 1]->OnTestIterationEnd(unit_test, iteration); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5363 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5364 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5365 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5366 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5367 |
// End TestEventRepeater |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5368 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5369 |
// This class generates an XML output file. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5370 |
class XmlUnitTestResultPrinter : public EmptyTestEventListener { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5371 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5372 |
explicit XmlUnitTestResultPrinter(const char* output_file); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5373 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5374 |
void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5375 |
void ListTestsMatchingFilter(const std::vector<TestSuite*>& test_suites); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5376 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5377 |
// Prints an XML summary of all unit tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5378 |
static void PrintXmlTestsList(std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5379 |
const std::vector<TestSuite*>& test_suites); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5380 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5381 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5382 |
// Is c a whitespace character that is normalized to a space character |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5383 |
// when it appears in an XML attribute value? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5384 |
static bool IsNormalizableWhitespace(char c) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5385 |
return c == 0x9 || c == 0xA || c == 0xD; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5386 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5387 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5388 |
// May c appear in a well-formed XML document? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5389 |
static bool IsValidXmlCharacter(char c) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5390 |
return IsNormalizableWhitespace(c) || c >= 0x20; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5391 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5392 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5393 |
// Returns an XML-escaped copy of the input string str. If |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5394 |
// is_attribute is true, the text is meant to appear as an attribute |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5395 |
// value, and normalizable whitespace is preserved by replacing it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5396 |
// with character references. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5397 |
static std::string EscapeXml(const std::string& str, bool is_attribute); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5398 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5399 |
// Returns the given string with all characters invalid in XML removed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5400 |
static std::string RemoveInvalidXmlCharacters(const std::string& str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5401 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5402 |
// Convenience wrapper around EscapeXml when str is an attribute value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5403 |
static std::string EscapeXmlAttribute(const std::string& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5404 |
return EscapeXml(str, true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5405 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5406 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5407 |
// Convenience wrapper around EscapeXml when str is not an attribute value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5408 |
static std::string EscapeXmlText(const char* str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5409 |
return EscapeXml(str, false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5410 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5411 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5412 |
// Verifies that the given attribute belongs to the given element and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5413 |
// streams the attribute as XML. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5414 |
static void OutputXmlAttribute(std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5415 |
const std::string& element_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5416 |
const std::string& name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5417 |
const std::string& value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5418 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5419 |
// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5420 |
static void OutputXmlCDataSection(::std::ostream* stream, const char* data); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5421 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5422 |
// Streams a test suite XML stanza containing the given test result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5423 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5424 |
// Requires: result.Failed() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5425 |
static void OutputXmlTestSuiteForTestResult(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5426 |
const TestResult& result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5427 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5428 |
// Streams an XML representation of a TestResult object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5429 |
static void OutputXmlTestResult(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5430 |
const TestResult& result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5431 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5432 |
// Streams an XML representation of a TestInfo object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5433 |
static void OutputXmlTestInfo(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5434 |
const char* test_suite_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5435 |
const TestInfo& test_info); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5436 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5437 |
// Prints an XML representation of a TestSuite object |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5438 |
static void PrintXmlTestSuite(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5439 |
const TestSuite& test_suite); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5440 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5441 |
// Prints an XML summary of unit_test to output stream out. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5442 |
static void PrintXmlUnitTest(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5443 |
const UnitTest& unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5444 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5445 |
// Produces a string representing the test properties in a result as space |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5446 |
// delimited XML attributes based on the property key="value" pairs. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5447 |
// When the std::string is not empty, it includes a space at the beginning, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5448 |
// to delimit this attribute from prior attributes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5449 |
static std::string TestPropertiesAsXmlAttributes(const TestResult& result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5450 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5451 |
// Streams an XML representation of the test properties of a TestResult |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5452 |
// object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5453 |
static void OutputXmlTestProperties(std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5454 |
const TestResult& result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5455 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5456 |
// The output file. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5457 |
const std::string output_file_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5458 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5459 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5460 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5461 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5462 |
// Creates a new XmlUnitTestResultPrinter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5463 |
XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5464 |
: output_file_(output_file) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5465 |
if (output_file_.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5466 |
GTEST_LOG_(FATAL) << "XML output file may not be null"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5467 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5468 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5469 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5470 |
// Called after the unit test ends. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5471 |
void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5472 |
int /*iteration*/) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5473 |
FILE* xmlout = OpenFileForWriting(output_file_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5474 |
std::stringstream stream; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5475 |
PrintXmlUnitTest(&stream, unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5476 |
fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5477 |
fclose(xmlout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5478 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5479 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5480 |
void XmlUnitTestResultPrinter::ListTestsMatchingFilter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5481 |
const std::vector<TestSuite*>& test_suites) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5482 |
FILE* xmlout = OpenFileForWriting(output_file_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5483 |
std::stringstream stream; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5484 |
PrintXmlTestsList(&stream, test_suites); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5485 |
fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5486 |
fclose(xmlout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5487 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5488 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5489 |
// Returns an XML-escaped copy of the input string str. If is_attribute |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5490 |
// is true, the text is meant to appear as an attribute value, and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5491 |
// normalizable whitespace is preserved by replacing it with character |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5492 |
// references. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5493 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5494 |
// Invalid XML characters in str, if any, are stripped from the output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5495 |
// It is expected that most, if not all, of the text processed by this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5496 |
// module will consist of ordinary English text. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5497 |
// If this module is ever modified to produce version 1.1 XML output, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5498 |
// most invalid characters can be retained using character references. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5499 |
std::string XmlUnitTestResultPrinter::EscapeXml( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5500 |
const std::string& str, bool is_attribute) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5501 |
Message m; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5502 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5503 |
for (size_t i = 0; i < str.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5504 |
const char ch = str[i]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5505 |
switch (ch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5506 |
case '<': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5507 |
m << "<"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5508 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5509 |
case '>': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5510 |
m << ">"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5511 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5512 |
case '&': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5513 |
m << "&"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5514 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5515 |
case '\'': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5516 |
if (is_attribute) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5517 |
m << "'"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5518 |
else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5519 |
m << '\''; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5520 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5521 |
case '"': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5522 |
if (is_attribute) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5523 |
m << """; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5524 |
else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5525 |
m << '"'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5526 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5527 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5528 |
if (IsValidXmlCharacter(ch)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5529 |
if (is_attribute && IsNormalizableWhitespace(ch)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5530 |
m << "&#x" << String::FormatByte(static_cast<unsigned char>(ch)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5531 |
<< ";"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5532 |
else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5533 |
m << ch; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5534 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5535 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5536 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5537 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5538 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5539 |
return m.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5540 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5541 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5542 |
// Returns the given string with all characters invalid in XML removed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5543 |
// Currently invalid characters are dropped from the string. An |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5544 |
// alternative is to replace them with certain characters such as . or ?. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5545 |
std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5546 |
const std::string& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5547 |
std::string output; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5548 |
output.reserve(str.size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5549 |
for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5550 |
if (IsValidXmlCharacter(*it)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5551 |
output.push_back(*it); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5552 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5553 |
return output; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5554 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5555 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5556 |
// The following routines generate an XML representation of a UnitTest |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5557 |
// object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5558 |
// GOOGLETEST_CM0009 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5559 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5560 |
// This is how Google Test concepts map to the DTD: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5561 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5562 |
// <testsuites name="AllTests"> <-- corresponds to a UnitTest object |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5563 |
// <testsuite name="testcase-name"> <-- corresponds to a TestSuite object |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5564 |
// <testcase name="test-name"> <-- corresponds to a TestInfo object |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5565 |
// <failure message="...">...</failure> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5566 |
// <failure message="...">...</failure> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5567 |
// <failure message="...">...</failure> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5568 |
// <-- individual assertion failures |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5569 |
// </testcase> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5570 |
// </testsuite> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5571 |
// </testsuites> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5572 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5573 |
// Formats the given time in milliseconds as seconds. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5574 |
std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5575 |
::std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5576 |
ss << (static_cast<double>(ms) * 1e-3); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5577 |
return ss.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5578 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5579 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5580 |
static bool PortableLocaltime(time_t seconds, struct tm* out) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5581 |
#if defined(_MSC_VER) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5582 |
return localtime_s(out, &seconds) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5583 |
#elif defined(__MINGW32__) || defined(__MINGW64__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5584 |
// MINGW <time.h> provides neither localtime_r nor localtime_s, but uses |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5585 |
// Windows' localtime(), which has a thread-local tm buffer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5586 |
struct tm* tm_ptr = localtime(&seconds); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5587 |
if (tm_ptr == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5588 |
*out = *tm_ptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5589 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5590 |
#elif defined(__STDC_LIB_EXT1__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5591 |
// Uses localtime_s when available as localtime_r is only available from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5592 |
// C23 standard. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5593 |
return localtime_s(&seconds, out) != nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5594 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5595 |
return localtime_r(&seconds, out) != nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5596 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5597 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5598 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5599 |
// Converts the given epoch time in milliseconds to a date string in the ISO |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5600 |
// 8601 format, without the timezone information. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5601 |
std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5602 |
struct tm time_struct; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5603 |
if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5604 |
return ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5605 |
// YYYY-MM-DDThh:mm:ss.sss |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5606 |
return StreamableToString(time_struct.tm_year + 1900) + "-" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5607 |
String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5608 |
String::FormatIntWidth2(time_struct.tm_mday) + "T" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5609 |
String::FormatIntWidth2(time_struct.tm_hour) + ":" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5610 |
String::FormatIntWidth2(time_struct.tm_min) + ":" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5611 |
String::FormatIntWidth2(time_struct.tm_sec) + "." + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5612 |
String::FormatIntWidthN(static_cast<int>(ms % 1000), 3); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5613 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5614 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5615 |
// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5616 |
void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5617 |
const char* data) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5618 |
const char* segment = data; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5619 |
*stream << "<![CDATA["; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5620 |
for (;;) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5621 |
const char* const next_segment = strstr(segment, "]]>"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5622 |
if (next_segment != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5623 |
stream->write( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5624 |
segment, static_cast<std::streamsize>(next_segment - segment)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5625 |
*stream << "]]>]]><![CDATA["; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5626 |
segment = next_segment + strlen("]]>"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5627 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5628 |
*stream << segment; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5629 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5630 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5631 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5632 |
*stream << "]]>"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5633 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5634 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5635 |
void XmlUnitTestResultPrinter::OutputXmlAttribute( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5636 |
std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5637 |
const std::string& element_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5638 |
const std::string& name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5639 |
const std::string& value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5640 |
const std::vector<std::string>& allowed_names = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5641 |
GetReservedOutputAttributesForElement(element_name); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5642 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5643 |
GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5644 |
allowed_names.end()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5645 |
<< "Attribute " << name << " is not allowed for element <" << element_name |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5646 |
<< ">."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5647 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5648 |
*stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5649 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5650 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5651 |
// Streams a test suite XML stanza containing the given test result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5652 |
void XmlUnitTestResultPrinter::OutputXmlTestSuiteForTestResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5653 |
::std::ostream* stream, const TestResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5654 |
// Output the boilerplate for a minimal test suite with one test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5655 |
*stream << " <testsuite"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5656 |
OutputXmlAttribute(stream, "testsuite", "name", "NonTestSuiteFailure"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5657 |
OutputXmlAttribute(stream, "testsuite", "tests", "1"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5658 |
OutputXmlAttribute(stream, "testsuite", "failures", "1"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5659 |
OutputXmlAttribute(stream, "testsuite", "disabled", "0"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5660 |
OutputXmlAttribute(stream, "testsuite", "skipped", "0"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5661 |
OutputXmlAttribute(stream, "testsuite", "errors", "0"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5662 |
OutputXmlAttribute(stream, "testsuite", "time", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5663 |
FormatTimeInMillisAsSeconds(result.elapsed_time())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5664 |
OutputXmlAttribute( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5665 |
stream, "testsuite", "timestamp", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5666 |
FormatEpochTimeInMillisAsIso8601(result.start_timestamp())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5667 |
*stream << ">"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5668 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5669 |
// Output the boilerplate for a minimal test case with a single test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5670 |
*stream << " <testcase"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5671 |
OutputXmlAttribute(stream, "testcase", "name", ""); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5672 |
OutputXmlAttribute(stream, "testcase", "status", "run"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5673 |
OutputXmlAttribute(stream, "testcase", "result", "completed"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5674 |
OutputXmlAttribute(stream, "testcase", "classname", ""); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5675 |
OutputXmlAttribute(stream, "testcase", "time", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5676 |
FormatTimeInMillisAsSeconds(result.elapsed_time())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5677 |
OutputXmlAttribute( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5678 |
stream, "testcase", "timestamp", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5679 |
FormatEpochTimeInMillisAsIso8601(result.start_timestamp())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5680 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5681 |
// Output the actual test result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5682 |
OutputXmlTestResult(stream, result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5683 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5684 |
// Complete the test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5685 |
*stream << " </testsuite>\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5686 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5687 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5688 |
// Prints an XML representation of a TestInfo object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5689 |
void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5690 |
const char* test_suite_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5691 |
const TestInfo& test_info) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5692 |
const TestResult& result = *test_info.result(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5693 |
const std::string kTestsuite = "testcase"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5694 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5695 |
if (test_info.is_in_another_shard()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5696 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5697 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5698 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5699 |
*stream << " <testcase"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5700 |
OutputXmlAttribute(stream, kTestsuite, "name", test_info.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5701 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5702 |
if (test_info.value_param() != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5703 |
OutputXmlAttribute(stream, kTestsuite, "value_param", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5704 |
test_info.value_param()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5705 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5706 |
if (test_info.type_param() != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5707 |
OutputXmlAttribute(stream, kTestsuite, "type_param", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5708 |
test_info.type_param()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5709 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5710 |
if (GTEST_FLAG(list_tests)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5711 |
OutputXmlAttribute(stream, kTestsuite, "file", test_info.file()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5712 |
OutputXmlAttribute(stream, kTestsuite, "line", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5713 |
StreamableToString(test_info.line())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5714 |
*stream << " />\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5715 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5716 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5717 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5718 |
OutputXmlAttribute(stream, kTestsuite, "status", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5719 |
test_info.should_run() ? "run" : "notrun"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5720 |
OutputXmlAttribute(stream, kTestsuite, "result", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5721 |
test_info.should_run() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5722 |
? (result.Skipped() ? "skipped" : "completed") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5723 |
: "suppressed"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5724 |
OutputXmlAttribute(stream, kTestsuite, "time", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5725 |
FormatTimeInMillisAsSeconds(result.elapsed_time())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5726 |
OutputXmlAttribute( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5727 |
stream, kTestsuite, "timestamp", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5728 |
FormatEpochTimeInMillisAsIso8601(result.start_timestamp())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5729 |
OutputXmlAttribute(stream, kTestsuite, "classname", test_suite_name); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5730 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5731 |
OutputXmlTestResult(stream, result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5732 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5733 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5734 |
void XmlUnitTestResultPrinter::OutputXmlTestResult(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5735 |
const TestResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5736 |
int failures = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5737 |
int skips = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5738 |
for (int i = 0; i < result.total_part_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5739 |
const TestPartResult& part = result.GetTestPartResult(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5740 |
if (part.failed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5741 |
if (++failures == 1 && skips == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5742 |
*stream << ">\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5743 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5744 |
const std::string location = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5745 |
internal::FormatCompilerIndependentFileLocation(part.file_name(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5746 |
part.line_number()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5747 |
const std::string summary = location + "\n" + part.summary(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5748 |
*stream << " <failure message=\"" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5749 |
<< EscapeXmlAttribute(summary) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5750 |
<< "\" type=\"\">"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5751 |
const std::string detail = location + "\n" + part.message(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5752 |
OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5753 |
*stream << "</failure>\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5754 |
} else if (part.skipped()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5755 |
if (++skips == 1 && failures == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5756 |
*stream << ">\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5757 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5758 |
const std::string location = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5759 |
internal::FormatCompilerIndependentFileLocation(part.file_name(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5760 |
part.line_number()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5761 |
const std::string summary = location + "\n" + part.summary(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5762 |
*stream << " <skipped message=\"" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5763 |
<< EscapeXmlAttribute(summary.c_str()) << "\">"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5764 |
const std::string detail = location + "\n" + part.message(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5765 |
OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5766 |
*stream << "</skipped>\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5767 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5768 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5769 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5770 |
if (failures == 0 && skips == 0 && result.test_property_count() == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5771 |
*stream << " />\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5772 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5773 |
if (failures == 0 && skips == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5774 |
*stream << ">\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5775 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5776 |
OutputXmlTestProperties(stream, result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5777 |
*stream << " </testcase>\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5778 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5779 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5780 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5781 |
// Prints an XML representation of a TestSuite object |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5782 |
void XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5783 |
const TestSuite& test_suite) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5784 |
const std::string kTestsuite = "testsuite"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5785 |
*stream << " <" << kTestsuite; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5786 |
OutputXmlAttribute(stream, kTestsuite, "name", test_suite.name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5787 |
OutputXmlAttribute(stream, kTestsuite, "tests", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5788 |
StreamableToString(test_suite.reportable_test_count())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5789 |
if (!GTEST_FLAG(list_tests)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5790 |
OutputXmlAttribute(stream, kTestsuite, "failures", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5791 |
StreamableToString(test_suite.failed_test_count())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5792 |
OutputXmlAttribute( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5793 |
stream, kTestsuite, "disabled", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5794 |
StreamableToString(test_suite.reportable_disabled_test_count())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5795 |
OutputXmlAttribute(stream, kTestsuite, "skipped", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5796 |
StreamableToString(test_suite.skipped_test_count())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5797 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5798 |
OutputXmlAttribute(stream, kTestsuite, "errors", "0"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5799 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5800 |
OutputXmlAttribute(stream, kTestsuite, "time", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5801 |
FormatTimeInMillisAsSeconds(test_suite.elapsed_time())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5802 |
OutputXmlAttribute( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5803 |
stream, kTestsuite, "timestamp", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5804 |
FormatEpochTimeInMillisAsIso8601(test_suite.start_timestamp())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5805 |
*stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5806 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5807 |
*stream << ">\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5808 |
for (int i = 0; i < test_suite.total_test_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5809 |
if (test_suite.GetTestInfo(i)->is_reportable()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5810 |
OutputXmlTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5811 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5812 |
*stream << " </" << kTestsuite << ">\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5813 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5814 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5815 |
// Prints an XML summary of unit_test to output stream out. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5816 |
void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5817 |
const UnitTest& unit_test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5818 |
const std::string kTestsuites = "testsuites"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5819 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5820 |
*stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5821 |
*stream << "<" << kTestsuites; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5822 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5823 |
OutputXmlAttribute(stream, kTestsuites, "tests", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5824 |
StreamableToString(unit_test.reportable_test_count())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5825 |
OutputXmlAttribute(stream, kTestsuites, "failures", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5826 |
StreamableToString(unit_test.failed_test_count())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5827 |
OutputXmlAttribute( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5828 |
stream, kTestsuites, "disabled", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5829 |
StreamableToString(unit_test.reportable_disabled_test_count())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5830 |
OutputXmlAttribute(stream, kTestsuites, "errors", "0"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5831 |
OutputXmlAttribute(stream, kTestsuites, "time", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5832 |
FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5833 |
OutputXmlAttribute( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5834 |
stream, kTestsuites, "timestamp", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5835 |
FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5836 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5837 |
if (GTEST_FLAG(shuffle)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5838 |
OutputXmlAttribute(stream, kTestsuites, "random_seed", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5839 |
StreamableToString(unit_test.random_seed())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5840 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5841 |
*stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5842 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5843 |
OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5844 |
*stream << ">\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5845 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5846 |
for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5847 |
if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5848 |
PrintXmlTestSuite(stream, *unit_test.GetTestSuite(i)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5849 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5850 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5851 |
// If there was a test failure outside of one of the test suites (like in a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5852 |
// test environment) include that in the output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5853 |
if (unit_test.ad_hoc_test_result().Failed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5854 |
OutputXmlTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5855 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5856 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5857 |
*stream << "</" << kTestsuites << ">\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5858 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5859 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5860 |
void XmlUnitTestResultPrinter::PrintXmlTestsList( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5861 |
std::ostream* stream, const std::vector<TestSuite*>& test_suites) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5862 |
const std::string kTestsuites = "testsuites"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5863 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5864 |
*stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5865 |
*stream << "<" << kTestsuites; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5866 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5867 |
int total_tests = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5868 |
for (auto test_suite : test_suites) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5869 |
total_tests += test_suite->total_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5870 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5871 |
OutputXmlAttribute(stream, kTestsuites, "tests", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5872 |
StreamableToString(total_tests)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5873 |
OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5874 |
*stream << ">\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5875 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5876 |
for (auto test_suite : test_suites) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5877 |
PrintXmlTestSuite(stream, *test_suite); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5878 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5879 |
*stream << "</" << kTestsuites << ">\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5880 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5881 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5882 |
// Produces a string representing the test properties in a result as space |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5883 |
// delimited XML attributes based on the property key="value" pairs. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5884 |
std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5885 |
const TestResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5886 |
Message attributes; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5887 |
for (int i = 0; i < result.test_property_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5888 |
const TestProperty& property = result.GetTestProperty(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5889 |
attributes << " " << property.key() << "=" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5890 |
<< "\"" << EscapeXmlAttribute(property.value()) << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5891 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5892 |
return attributes.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5893 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5894 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5895 |
void XmlUnitTestResultPrinter::OutputXmlTestProperties( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5896 |
std::ostream* stream, const TestResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5897 |
const std::string kProperties = "properties"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5898 |
const std::string kProperty = "property"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5899 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5900 |
if (result.test_property_count() <= 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5901 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5902 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5903 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5904 |
*stream << "<" << kProperties << ">\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5905 |
for (int i = 0; i < result.test_property_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5906 |
const TestProperty& property = result.GetTestProperty(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5907 |
*stream << "<" << kProperty; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5908 |
*stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5909 |
*stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5910 |
*stream << "/>\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5911 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5912 |
*stream << "</" << kProperties << ">\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5913 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5914 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5915 |
// End XmlUnitTestResultPrinter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5916 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5917 |
// This class generates an JSON output file. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5918 |
class JsonUnitTestResultPrinter : public EmptyTestEventListener { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5919 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5920 |
explicit JsonUnitTestResultPrinter(const char* output_file); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5921 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5922 |
void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5923 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5924 |
// Prints an JSON summary of all unit tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5925 |
static void PrintJsonTestList(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5926 |
const std::vector<TestSuite*>& test_suites); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5927 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5928 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5929 |
// Returns an JSON-escaped copy of the input string str. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5930 |
static std::string EscapeJson(const std::string& str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5931 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5932 |
//// Verifies that the given attribute belongs to the given element and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5933 |
//// streams the attribute as JSON. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5934 |
static void OutputJsonKey(std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5935 |
const std::string& element_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5936 |
const std::string& name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5937 |
const std::string& value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5938 |
const std::string& indent, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5939 |
bool comma = true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5940 |
static void OutputJsonKey(std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5941 |
const std::string& element_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5942 |
const std::string& name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5943 |
int value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5944 |
const std::string& indent, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5945 |
bool comma = true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5946 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5947 |
// Streams a test suite JSON stanza containing the given test result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5948 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5949 |
// Requires: result.Failed() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5950 |
static void OutputJsonTestSuiteForTestResult(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5951 |
const TestResult& result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5952 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5953 |
// Streams a JSON representation of a TestResult object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5954 |
static void OutputJsonTestResult(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5955 |
const TestResult& result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5956 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5957 |
// Streams a JSON representation of a TestInfo object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5958 |
static void OutputJsonTestInfo(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5959 |
const char* test_suite_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5960 |
const TestInfo& test_info); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5961 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5962 |
// Prints a JSON representation of a TestSuite object |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5963 |
static void PrintJsonTestSuite(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5964 |
const TestSuite& test_suite); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5965 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5966 |
// Prints a JSON summary of unit_test to output stream out. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5967 |
static void PrintJsonUnitTest(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5968 |
const UnitTest& unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5969 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5970 |
// Produces a string representing the test properties in a result as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5971 |
// a JSON dictionary. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5972 |
static std::string TestPropertiesAsJson(const TestResult& result, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5973 |
const std::string& indent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5974 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5975 |
// The output file. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5976 |
const std::string output_file_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5977 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5978 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(JsonUnitTestResultPrinter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5979 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5980 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5981 |
// Creates a new JsonUnitTestResultPrinter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5982 |
JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5983 |
: output_file_(output_file) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5984 |
if (output_file_.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5985 |
GTEST_LOG_(FATAL) << "JSON output file may not be null"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5986 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5987 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5988 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5989 |
void JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5990 |
int /*iteration*/) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5991 |
FILE* jsonout = OpenFileForWriting(output_file_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5992 |
std::stringstream stream; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5993 |
PrintJsonUnitTest(&stream, unit_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5994 |
fprintf(jsonout, "%s", StringStreamToString(&stream).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5995 |
fclose(jsonout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5996 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5997 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5998 |
// Returns an JSON-escaped copy of the input string str. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5999 |
std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6000 |
Message m; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6001 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6002 |
for (size_t i = 0; i < str.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6003 |
const char ch = str[i]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6004 |
switch (ch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6005 |
case '\\': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6006 |
case '"': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6007 |
case '/': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6008 |
m << '\\' << ch; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6009 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6010 |
case '\b': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6011 |
m << "\\b"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6012 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6013 |
case '\t': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6014 |
m << "\\t"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6015 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6016 |
case '\n': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6017 |
m << "\\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6018 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6019 |
case '\f': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6020 |
m << "\\f"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6021 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6022 |
case '\r': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6023 |
m << "\\r"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6024 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6025 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6026 |
if (ch < ' ') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6027 |
m << "\\u00" << String::FormatByte(static_cast<unsigned char>(ch)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6028 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6029 |
m << ch; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6030 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6031 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6032 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6033 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6034 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6035 |
return m.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6036 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6037 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6038 |
// The following routines generate an JSON representation of a UnitTest |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6039 |
// object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6040 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6041 |
// Formats the given time in milliseconds as seconds. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6042 |
static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6043 |
::std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6044 |
ss << (static_cast<double>(ms) * 1e-3) << "s"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6045 |
return ss.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6046 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6047 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6048 |
// Converts the given epoch time in milliseconds to a date string in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6049 |
// RFC3339 format, without the timezone information. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6050 |
static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6051 |
struct tm time_struct; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6052 |
if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6053 |
return ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6054 |
// YYYY-MM-DDThh:mm:ss |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6055 |
return StreamableToString(time_struct.tm_year + 1900) + "-" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6056 |
String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6057 |
String::FormatIntWidth2(time_struct.tm_mday) + "T" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6058 |
String::FormatIntWidth2(time_struct.tm_hour) + ":" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6059 |
String::FormatIntWidth2(time_struct.tm_min) + ":" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6060 |
String::FormatIntWidth2(time_struct.tm_sec) + "Z"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6061 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6062 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6063 |
static inline std::string Indent(size_t width) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6064 |
return std::string(width, ' '); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6065 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6066 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6067 |
void JsonUnitTestResultPrinter::OutputJsonKey( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6068 |
std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6069 |
const std::string& element_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6070 |
const std::string& name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6071 |
const std::string& value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6072 |
const std::string& indent, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6073 |
bool comma) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6074 |
const std::vector<std::string>& allowed_names = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6075 |
GetReservedOutputAttributesForElement(element_name); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6076 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6077 |
GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6078 |
allowed_names.end()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6079 |
<< "Key \"" << name << "\" is not allowed for value \"" << element_name |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6080 |
<< "\"."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6081 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6082 |
*stream << indent << "\"" << name << "\": \"" << EscapeJson(value) << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6083 |
if (comma) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6084 |
*stream << ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6085 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6086 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6087 |
void JsonUnitTestResultPrinter::OutputJsonKey( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6088 |
std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6089 |
const std::string& element_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6090 |
const std::string& name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6091 |
int value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6092 |
const std::string& indent, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6093 |
bool comma) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6094 |
const std::vector<std::string>& allowed_names = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6095 |
GetReservedOutputAttributesForElement(element_name); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6096 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6097 |
GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6098 |
allowed_names.end()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6099 |
<< "Key \"" << name << "\" is not allowed for value \"" << element_name |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6100 |
<< "\"."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6101 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6102 |
*stream << indent << "\"" << name << "\": " << StreamableToString(value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6103 |
if (comma) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6104 |
*stream << ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6105 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6106 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6107 |
// Streams a test suite JSON stanza containing the given test result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6108 |
void JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6109 |
::std::ostream* stream, const TestResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6110 |
// Output the boilerplate for a new test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6111 |
*stream << Indent(4) << "{\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6112 |
OutputJsonKey(stream, "testsuite", "name", "NonTestSuiteFailure", Indent(6)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6113 |
OutputJsonKey(stream, "testsuite", "tests", 1, Indent(6)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6114 |
if (!GTEST_FLAG(list_tests)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6115 |
OutputJsonKey(stream, "testsuite", "failures", 1, Indent(6)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6116 |
OutputJsonKey(stream, "testsuite", "disabled", 0, Indent(6)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6117 |
OutputJsonKey(stream, "testsuite", "skipped", 0, Indent(6)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6118 |
OutputJsonKey(stream, "testsuite", "errors", 0, Indent(6)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6119 |
OutputJsonKey(stream, "testsuite", "time", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6120 |
FormatTimeInMillisAsDuration(result.elapsed_time()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6121 |
Indent(6)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6122 |
OutputJsonKey(stream, "testsuite", "timestamp", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6123 |
FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6124 |
Indent(6)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6125 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6126 |
*stream << Indent(6) << "\"testsuite\": [\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6127 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6128 |
// Output the boilerplate for a new test case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6129 |
*stream << Indent(8) << "{\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6130 |
OutputJsonKey(stream, "testcase", "name", "", Indent(10)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6131 |
OutputJsonKey(stream, "testcase", "status", "RUN", Indent(10)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6132 |
OutputJsonKey(stream, "testcase", "result", "COMPLETED", Indent(10)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6133 |
OutputJsonKey(stream, "testcase", "timestamp", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6134 |
FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6135 |
Indent(10)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6136 |
OutputJsonKey(stream, "testcase", "time", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6137 |
FormatTimeInMillisAsDuration(result.elapsed_time()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6138 |
Indent(10)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6139 |
OutputJsonKey(stream, "testcase", "classname", "", Indent(10), false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6140 |
*stream << TestPropertiesAsJson(result, Indent(10)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6141 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6142 |
// Output the actual test result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6143 |
OutputJsonTestResult(stream, result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6144 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6145 |
// Finish the test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6146 |
*stream << "\n" << Indent(6) << "]\n" << Indent(4) << "}"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6147 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6148 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6149 |
// Prints a JSON representation of a TestInfo object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6150 |
void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6151 |
const char* test_suite_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6152 |
const TestInfo& test_info) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6153 |
const TestResult& result = *test_info.result(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6154 |
const std::string kTestsuite = "testcase"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6155 |
const std::string kIndent = Indent(10); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6156 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6157 |
*stream << Indent(8) << "{\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6158 |
OutputJsonKey(stream, kTestsuite, "name", test_info.name(), kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6159 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6160 |
if (test_info.value_param() != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6161 |
OutputJsonKey(stream, kTestsuite, "value_param", test_info.value_param(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6162 |
kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6163 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6164 |
if (test_info.type_param() != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6165 |
OutputJsonKey(stream, kTestsuite, "type_param", test_info.type_param(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6166 |
kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6167 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6168 |
if (GTEST_FLAG(list_tests)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6169 |
OutputJsonKey(stream, kTestsuite, "file", test_info.file(), kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6170 |
OutputJsonKey(stream, kTestsuite, "line", test_info.line(), kIndent, false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6171 |
*stream << "\n" << Indent(8) << "}"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6172 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6173 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6174 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6175 |
OutputJsonKey(stream, kTestsuite, "status", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6176 |
test_info.should_run() ? "RUN" : "NOTRUN", kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6177 |
OutputJsonKey(stream, kTestsuite, "result", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6178 |
test_info.should_run() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6179 |
? (result.Skipped() ? "SKIPPED" : "COMPLETED") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6180 |
: "SUPPRESSED", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6181 |
kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6182 |
OutputJsonKey(stream, kTestsuite, "timestamp", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6183 |
FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6184 |
kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6185 |
OutputJsonKey(stream, kTestsuite, "time", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6186 |
FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6187 |
OutputJsonKey(stream, kTestsuite, "classname", test_suite_name, kIndent, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6188 |
false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6189 |
*stream << TestPropertiesAsJson(result, kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6190 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6191 |
OutputJsonTestResult(stream, result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6192 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6193 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6194 |
void JsonUnitTestResultPrinter::OutputJsonTestResult(::std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6195 |
const TestResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6196 |
const std::string kIndent = Indent(10); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6197 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6198 |
int failures = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6199 |
for (int i = 0; i < result.total_part_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6200 |
const TestPartResult& part = result.GetTestPartResult(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6201 |
if (part.failed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6202 |
*stream << ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6203 |
if (++failures == 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6204 |
*stream << kIndent << "\"" << "failures" << "\": [\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6205 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6206 |
const std::string location = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6207 |
internal::FormatCompilerIndependentFileLocation(part.file_name(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6208 |
part.line_number()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6209 |
const std::string message = EscapeJson(location + "\n" + part.message()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6210 |
*stream << kIndent << " {\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6211 |
<< kIndent << " \"failure\": \"" << message << "\",\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6212 |
<< kIndent << " \"type\": \"\"\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6213 |
<< kIndent << " }"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6214 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6215 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6216 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6217 |
if (failures > 0) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6218 |
*stream << "\n" << kIndent << "]"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6219 |
*stream << "\n" << Indent(8) << "}"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6220 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6221 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6222 |
// Prints an JSON representation of a TestSuite object |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6223 |
void JsonUnitTestResultPrinter::PrintJsonTestSuite( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6224 |
std::ostream* stream, const TestSuite& test_suite) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6225 |
const std::string kTestsuite = "testsuite"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6226 |
const std::string kIndent = Indent(6); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6227 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6228 |
*stream << Indent(4) << "{\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6229 |
OutputJsonKey(stream, kTestsuite, "name", test_suite.name(), kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6230 |
OutputJsonKey(stream, kTestsuite, "tests", test_suite.reportable_test_count(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6231 |
kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6232 |
if (!GTEST_FLAG(list_tests)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6233 |
OutputJsonKey(stream, kTestsuite, "failures", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6234 |
test_suite.failed_test_count(), kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6235 |
OutputJsonKey(stream, kTestsuite, "disabled", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6236 |
test_suite.reportable_disabled_test_count(), kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6237 |
OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6238 |
OutputJsonKey( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6239 |
stream, kTestsuite, "timestamp", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6240 |
FormatEpochTimeInMillisAsRFC3339(test_suite.start_timestamp()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6241 |
kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6242 |
OutputJsonKey(stream, kTestsuite, "time", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6243 |
FormatTimeInMillisAsDuration(test_suite.elapsed_time()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6244 |
kIndent, false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6245 |
*stream << TestPropertiesAsJson(test_suite.ad_hoc_test_result(), kIndent) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6246 |
<< ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6247 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6248 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6249 |
*stream << kIndent << "\"" << kTestsuite << "\": [\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6250 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6251 |
bool comma = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6252 |
for (int i = 0; i < test_suite.total_test_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6253 |
if (test_suite.GetTestInfo(i)->is_reportable()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6254 |
if (comma) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6255 |
*stream << ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6256 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6257 |
comma = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6258 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6259 |
OutputJsonTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6260 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6261 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6262 |
*stream << "\n" << kIndent << "]\n" << Indent(4) << "}"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6263 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6264 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6265 |
// Prints a JSON summary of unit_test to output stream out. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6266 |
void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6267 |
const UnitTest& unit_test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6268 |
const std::string kTestsuites = "testsuites"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6269 |
const std::string kIndent = Indent(2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6270 |
*stream << "{\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6271 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6272 |
OutputJsonKey(stream, kTestsuites, "tests", unit_test.reportable_test_count(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6273 |
kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6274 |
OutputJsonKey(stream, kTestsuites, "failures", unit_test.failed_test_count(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6275 |
kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6276 |
OutputJsonKey(stream, kTestsuites, "disabled", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6277 |
unit_test.reportable_disabled_test_count(), kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6278 |
OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6279 |
if (GTEST_FLAG(shuffle)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6280 |
OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6281 |
kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6282 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6283 |
OutputJsonKey(stream, kTestsuites, "timestamp", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6284 |
FormatEpochTimeInMillisAsRFC3339(unit_test.start_timestamp()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6285 |
kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6286 |
OutputJsonKey(stream, kTestsuites, "time", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6287 |
FormatTimeInMillisAsDuration(unit_test.elapsed_time()), kIndent, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6288 |
false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6289 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6290 |
*stream << TestPropertiesAsJson(unit_test.ad_hoc_test_result(), kIndent) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6291 |
<< ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6292 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6293 |
OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6294 |
*stream << kIndent << "\"" << kTestsuites << "\": [\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6295 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6296 |
bool comma = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6297 |
for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6298 |
if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6299 |
if (comma) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6300 |
*stream << ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6301 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6302 |
comma = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6303 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6304 |
PrintJsonTestSuite(stream, *unit_test.GetTestSuite(i)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6305 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6306 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6307 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6308 |
// If there was a test failure outside of one of the test suites (like in a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6309 |
// test environment) include that in the output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6310 |
if (unit_test.ad_hoc_test_result().Failed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6311 |
OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6312 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6313 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6314 |
*stream << "\n" << kIndent << "]\n" << "}\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6315 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6316 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6317 |
void JsonUnitTestResultPrinter::PrintJsonTestList( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6318 |
std::ostream* stream, const std::vector<TestSuite*>& test_suites) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6319 |
const std::string kTestsuites = "testsuites"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6320 |
const std::string kIndent = Indent(2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6321 |
*stream << "{\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6322 |
int total_tests = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6323 |
for (auto test_suite : test_suites) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6324 |
total_tests += test_suite->total_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6325 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6326 |
OutputJsonKey(stream, kTestsuites, "tests", total_tests, kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6327 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6328 |
OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6329 |
*stream << kIndent << "\"" << kTestsuites << "\": [\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6330 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6331 |
for (size_t i = 0; i < test_suites.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6332 |
if (i != 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6333 |
*stream << ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6334 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6335 |
PrintJsonTestSuite(stream, *test_suites[i]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6336 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6337 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6338 |
*stream << "\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6339 |
<< kIndent << "]\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6340 |
<< "}\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6341 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6342 |
// Produces a string representing the test properties in a result as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6343 |
// a JSON dictionary. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6344 |
std::string JsonUnitTestResultPrinter::TestPropertiesAsJson( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6345 |
const TestResult& result, const std::string& indent) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6346 |
Message attributes; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6347 |
for (int i = 0; i < result.test_property_count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6348 |
const TestProperty& property = result.GetTestProperty(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6349 |
attributes << ",\n" << indent << "\"" << property.key() << "\": " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6350 |
<< "\"" << EscapeJson(property.value()) << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6351 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6352 |
return attributes.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6353 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6354 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6355 |
// End JsonUnitTestResultPrinter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6356 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6357 |
#if GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6358 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6359 |
// Checks if str contains '=', '&', '%' or '\n' characters. If yes, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6360 |
// replaces them by "%xx" where xx is their hexadecimal value. For |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6361 |
// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6362 |
// in both time and space -- important as the input str may contain an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6363 |
// arbitrarily long test failure message and stack trace. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6364 |
std::string StreamingListener::UrlEncode(const char* str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6365 |
std::string result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6366 |
result.reserve(strlen(str) + 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6367 |
for (char ch = *str; ch != '\0'; ch = *++str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6368 |
switch (ch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6369 |
case '%': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6370 |
case '=': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6371 |
case '&': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6372 |
case '\n': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6373 |
result.append("%" + String::FormatByte(static_cast<unsigned char>(ch))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6374 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6375 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6376 |
result.push_back(ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6377 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6378 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6379 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6380 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6381 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6382 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6383 |
void StreamingListener::SocketWriter::MakeConnection() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6384 |
GTEST_CHECK_(sockfd_ == -1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6385 |
<< "MakeConnection() can't be called when there is already a connection."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6386 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6387 |
addrinfo hints; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6388 |
memset(&hints, 0, sizeof(hints)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6389 |
hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6390 |
hints.ai_socktype = SOCK_STREAM; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6391 |
addrinfo* servinfo = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6392 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6393 |
// Use the getaddrinfo() to get a linked list of IP addresses for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6394 |
// the given host name. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6395 |
const int error_num = getaddrinfo( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6396 |
host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6397 |
if (error_num != 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6398 |
GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6399 |
<< gai_strerror(error_num); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6400 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6401 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6402 |
// Loop through all the results and connect to the first we can. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6403 |
for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6404 |
cur_addr = cur_addr->ai_next) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6405 |
sockfd_ = socket( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6406 |
cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6407 |
if (sockfd_ != -1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6408 |
// Connect the client socket to the server socket. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6409 |
if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6410 |
close(sockfd_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6411 |
sockfd_ = -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6412 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6413 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6414 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6415 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6416 |
freeaddrinfo(servinfo); // all done with this structure |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6417 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6418 |
if (sockfd_ == -1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6419 |
GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6420 |
<< host_name_ << ":" << port_num_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6421 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6422 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6423 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6424 |
// End of class Streaming Listener |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6425 |
#endif // GTEST_CAN_STREAM_RESULTS__ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6426 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6427 |
// class OsStackTraceGetter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6428 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6429 |
const char* const OsStackTraceGetterInterface::kElidedFramesMarker = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6430 |
"... " GTEST_NAME_ " internal frames ..."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6431 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6432 |
std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6433 |
GTEST_LOCK_EXCLUDED_(mutex_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6434 |
#if GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6435 |
std::string result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6436 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6437 |
if (max_depth <= 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6438 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6439 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6440 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6441 |
max_depth = std::min(max_depth, kMaxStackTraceDepth); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6442 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6443 |
std::vector<void*> raw_stack(max_depth); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6444 |
// Skips the frames requested by the caller, plus this function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6445 |
const int raw_stack_size = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6446 |
absl::GetStackTrace(&raw_stack[0], max_depth, skip_count + 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6447 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6448 |
void* caller_frame = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6449 |
{ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6450 |
MutexLock lock(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6451 |
caller_frame = caller_frame_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6452 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6453 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6454 |
for (int i = 0; i < raw_stack_size; ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6455 |
if (raw_stack[i] == caller_frame && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6456 |
!GTEST_FLAG(show_internal_stack_frames)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6457 |
// Add a marker to the trace and stop adding frames. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6458 |
absl::StrAppend(&result, kElidedFramesMarker, "\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6459 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6460 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6461 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6462 |
char tmp[1024]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6463 |
const char* symbol = "(unknown)"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6464 |
if (absl::Symbolize(raw_stack[i], tmp, sizeof(tmp))) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6465 |
symbol = tmp; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6466 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6467 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6468 |
char line[1024]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6469 |
snprintf(line, sizeof(line), " %p: %s\n", raw_stack[i], symbol); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6470 |
result += line; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6471 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6472 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6473 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6474 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6475 |
#else // !GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6476 |
static_cast<void>(max_depth); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6477 |
static_cast<void>(skip_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6478 |
return ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6479 |
#endif // GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6480 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6481 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6482 |
void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6483 |
#if GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6484 |
void* caller_frame = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6485 |
if (absl::GetStackTrace(&caller_frame, 1, 3) <= 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6486 |
caller_frame = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6487 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6488 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6489 |
MutexLock lock(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6490 |
caller_frame_ = caller_frame; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6491 |
#endif // GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6492 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6493 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6494 |
// A helper class that creates the premature-exit file in its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6495 |
// constructor and deletes the file in its destructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6496 |
class ScopedPrematureExitFile { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6497 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6498 |
explicit ScopedPrematureExitFile(const char* premature_exit_filepath) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6499 |
: premature_exit_filepath_(premature_exit_filepath ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6500 |
premature_exit_filepath : "") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6501 |
// If a path to the premature-exit file is specified... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6502 |
if (!premature_exit_filepath_.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6503 |
// create the file with a single "0" character in it. I/O |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6504 |
// errors are ignored as there's nothing better we can do and we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6505 |
// don't want to fail the test because of this. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6506 |
FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6507 |
fwrite("0", 1, 1, pfile); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6508 |
fclose(pfile); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6509 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6510 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6511 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6512 |
~ScopedPrematureExitFile() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6513 |
#if !defined GTEST_OS_ESP8266 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6514 |
if (!premature_exit_filepath_.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6515 |
int retval = remove(premature_exit_filepath_.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6516 |
if (retval) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6517 |
GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \"" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6518 |
<< premature_exit_filepath_ << "\" with error " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6519 |
<< retval; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6520 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6521 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6522 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6523 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6524 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6525 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6526 |
const std::string premature_exit_filepath_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6527 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6528 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6529 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6530 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6531 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6532 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6533 |
// class TestEventListeners |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6534 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6535 |
TestEventListeners::TestEventListeners() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6536 |
: repeater_(new internal::TestEventRepeater()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6537 |
default_result_printer_(nullptr), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6538 |
default_xml_generator_(nullptr) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6539 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6540 |
TestEventListeners::~TestEventListeners() { delete repeater_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6541 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6542 |
// Returns the standard listener responsible for the default console |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6543 |
// output. Can be removed from the listeners list to shut down default |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6544 |
// console output. Note that removing this object from the listener list |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6545 |
// with Release transfers its ownership to the user. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6546 |
void TestEventListeners::Append(TestEventListener* listener) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6547 |
repeater_->Append(listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6548 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6549 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6550 |
// Removes the given event listener from the list and returns it. It then |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6551 |
// becomes the caller's responsibility to delete the listener. Returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6552 |
// NULL if the listener is not found in the list. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6553 |
TestEventListener* TestEventListeners::Release(TestEventListener* listener) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6554 |
if (listener == default_result_printer_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6555 |
default_result_printer_ = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6556 |
else if (listener == default_xml_generator_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6557 |
default_xml_generator_ = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6558 |
return repeater_->Release(listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6559 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6560 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6561 |
// Returns repeater that broadcasts the TestEventListener events to all |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6562 |
// subscribers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6563 |
TestEventListener* TestEventListeners::repeater() { return repeater_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6564 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6565 |
// Sets the default_result_printer attribute to the provided listener. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6566 |
// The listener is also added to the listener list and previous |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6567 |
// default_result_printer is removed from it and deleted. The listener can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6568 |
// also be NULL in which case it will not be added to the list. Does |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6569 |
// nothing if the previous and the current listener objects are the same. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6570 |
void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6571 |
if (default_result_printer_ != listener) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6572 |
// It is an error to pass this method a listener that is already in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6573 |
// list. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6574 |
delete Release(default_result_printer_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6575 |
default_result_printer_ = listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6576 |
if (listener != nullptr) Append(listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6577 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6578 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6579 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6580 |
// Sets the default_xml_generator attribute to the provided listener. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6581 |
// listener is also added to the listener list and previous |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6582 |
// default_xml_generator is removed from it and deleted. The listener can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6583 |
// also be NULL in which case it will not be added to the list. Does |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6584 |
// nothing if the previous and the current listener objects are the same. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6585 |
void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6586 |
if (default_xml_generator_ != listener) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6587 |
// It is an error to pass this method a listener that is already in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6588 |
// list. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6589 |
delete Release(default_xml_generator_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6590 |
default_xml_generator_ = listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6591 |
if (listener != nullptr) Append(listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6592 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6593 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6594 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6595 |
// Controls whether events will be forwarded by the repeater to the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6596 |
// listeners in the list. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6597 |
bool TestEventListeners::EventForwardingEnabled() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6598 |
return repeater_->forwarding_enabled(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6599 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6600 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6601 |
void TestEventListeners::SuppressEventForwarding() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6602 |
repeater_->set_forwarding_enabled(false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6603 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6604 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6605 |
// class UnitTest |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6606 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6607 |
// Gets the singleton UnitTest object. The first time this method is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6608 |
// called, a UnitTest object is constructed and returned. Consecutive |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6609 |
// calls will return the same object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6610 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6611 |
// We don't protect this under mutex_ as a user is not supposed to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6612 |
// call this before main() starts, from which point on the return |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6613 |
// value will never change. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6614 |
UnitTest* UnitTest::GetInstance() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6615 |
// CodeGear C++Builder insists on a public destructor for the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6616 |
// default implementation. Use this implementation to keep good OO |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6617 |
// design with private destructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6618 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6619 |
#if defined(__BORLANDC__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6620 |
static UnitTest* const instance = new UnitTest; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6621 |
return instance; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6622 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6623 |
static UnitTest instance; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6624 |
return &instance; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6625 |
#endif // defined(__BORLANDC__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6626 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6627 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6628 |
// Gets the number of successful test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6629 |
int UnitTest::successful_test_suite_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6630 |
return impl()->successful_test_suite_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6631 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6632 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6633 |
// Gets the number of failed test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6634 |
int UnitTest::failed_test_suite_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6635 |
return impl()->failed_test_suite_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6636 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6637 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6638 |
// Gets the number of all test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6639 |
int UnitTest::total_test_suite_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6640 |
return impl()->total_test_suite_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6641 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6642 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6643 |
// Gets the number of all test suites that contain at least one test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6644 |
// that should run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6645 |
int UnitTest::test_suite_to_run_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6646 |
return impl()->test_suite_to_run_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6647 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6648 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6649 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6650 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6651 |
int UnitTest::successful_test_case_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6652 |
return impl()->successful_test_suite_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6653 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6654 |
int UnitTest::failed_test_case_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6655 |
return impl()->failed_test_suite_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6656 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6657 |
int UnitTest::total_test_case_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6658 |
return impl()->total_test_suite_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6659 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6660 |
int UnitTest::test_case_to_run_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6661 |
return impl()->test_suite_to_run_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6662 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6663 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6664 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6665 |
// Gets the number of successful tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6666 |
int UnitTest::successful_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6667 |
return impl()->successful_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6668 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6669 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6670 |
// Gets the number of skipped tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6671 |
int UnitTest::skipped_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6672 |
return impl()->skipped_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6673 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6674 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6675 |
// Gets the number of failed tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6676 |
int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6677 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6678 |
// Gets the number of disabled tests that will be reported in the XML report. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6679 |
int UnitTest::reportable_disabled_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6680 |
return impl()->reportable_disabled_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6681 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6682 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6683 |
// Gets the number of disabled tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6684 |
int UnitTest::disabled_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6685 |
return impl()->disabled_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6686 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6687 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6688 |
// Gets the number of tests to be printed in the XML report. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6689 |
int UnitTest::reportable_test_count() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6690 |
return impl()->reportable_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6691 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6692 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6693 |
// Gets the number of all tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6694 |
int UnitTest::total_test_count() const { return impl()->total_test_count(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6695 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6696 |
// Gets the number of tests that should run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6697 |
int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6698 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6699 |
// Gets the time of the test program start, in ms from the start of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6700 |
// UNIX epoch. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6701 |
internal::TimeInMillis UnitTest::start_timestamp() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6702 |
return impl()->start_timestamp(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6703 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6704 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6705 |
// Gets the elapsed time, in milliseconds. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6706 |
internal::TimeInMillis UnitTest::elapsed_time() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6707 |
return impl()->elapsed_time(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6708 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6709 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6710 |
// Returns true if and only if the unit test passed (i.e. all test suites |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6711 |
// passed). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6712 |
bool UnitTest::Passed() const { return impl()->Passed(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6713 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6714 |
// Returns true if and only if the unit test failed (i.e. some test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6715 |
// failed or something outside of all tests failed). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6716 |
bool UnitTest::Failed() const { return impl()->Failed(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6717 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6718 |
// Gets the i-th test suite among all the test suites. i can range from 0 to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6719 |
// total_test_suite_count() - 1. If i is not in that range, returns NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6720 |
const TestSuite* UnitTest::GetTestSuite(int i) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6721 |
return impl()->GetTestSuite(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6722 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6723 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6724 |
// Legacy API is deprecated but still available |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6725 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6726 |
const TestCase* UnitTest::GetTestCase(int i) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6727 |
return impl()->GetTestCase(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6728 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6729 |
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6730 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6731 |
// Returns the TestResult containing information on test failures and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6732 |
// properties logged outside of individual test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6733 |
const TestResult& UnitTest::ad_hoc_test_result() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6734 |
return *impl()->ad_hoc_test_result(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6735 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6736 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6737 |
// Gets the i-th test suite among all the test suites. i can range from 0 to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6738 |
// total_test_suite_count() - 1. If i is not in that range, returns NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6739 |
TestSuite* UnitTest::GetMutableTestSuite(int i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6740 |
return impl()->GetMutableSuiteCase(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6741 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6742 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6743 |
// Returns the list of event listeners that can be used to track events |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6744 |
// inside Google Test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6745 |
TestEventListeners& UnitTest::listeners() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6746 |
return *impl()->listeners(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6747 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6748 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6749 |
// Registers and returns a global test environment. When a test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6750 |
// program is run, all global test environments will be set-up in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6751 |
// order they were registered. After all tests in the program have |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6752 |
// finished, all global test environments will be torn-down in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6753 |
// *reverse* order they were registered. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6754 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6755 |
// The UnitTest object takes ownership of the given environment. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6756 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6757 |
// We don't protect this under mutex_, as we only support calling it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6758 |
// from the main thread. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6759 |
Environment* UnitTest::AddEnvironment(Environment* env) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6760 |
if (env == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6761 |
return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6762 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6763 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6764 |
impl_->environments().push_back(env); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6765 |
return env; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6766 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6767 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6768 |
// Adds a TestPartResult to the current TestResult object. All Google Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6769 |
// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6770 |
// this to report their results. The user code should use the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6771 |
// assertion macros instead of calling this directly. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6772 |
void UnitTest::AddTestPartResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6773 |
TestPartResult::Type result_type, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6774 |
const char* file_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6775 |
int line_number, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6776 |
const std::string& message, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6777 |
const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6778 |
Message msg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6779 |
msg << message; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6780 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6781 |
internal::MutexLock lock(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6782 |
if (impl_->gtest_trace_stack().size() > 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6783 |
msg << "\n" << GTEST_NAME_ << " trace:"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6784 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6785 |
for (size_t i = impl_->gtest_trace_stack().size(); i > 0; --i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6786 |
const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6787 |
msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6788 |
<< " " << trace.message; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6789 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6790 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6791 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6792 |
if (os_stack_trace.c_str() != nullptr && !os_stack_trace.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6793 |
msg << internal::kStackTraceMarker << os_stack_trace; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6794 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6795 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6796 |
const TestPartResult result = TestPartResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6797 |
result_type, file_name, line_number, msg.GetString().c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6798 |
impl_->GetTestPartResultReporterForCurrentThread()-> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6799 |
ReportTestPartResult(result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6800 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6801 |
if (result_type != TestPartResult::kSuccess && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6802 |
result_type != TestPartResult::kSkip) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6803 |
// gtest_break_on_failure takes precedence over |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6804 |
// gtest_throw_on_failure. This allows a user to set the latter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6805 |
// in the code (perhaps in order to use Google Test assertions |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6806 |
// with another testing framework) and specify the former on the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6807 |
// command line for debugging. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6808 |
if (GTEST_FLAG(break_on_failure)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6809 |
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6810 |
// Using DebugBreak on Windows allows gtest to still break into a debugger |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6811 |
// when a failure happens and both the --gtest_break_on_failure and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6812 |
// the --gtest_catch_exceptions flags are specified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6813 |
DebugBreak(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6814 |
#elif (!defined(__native_client__)) && \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6815 |
((defined(__clang__) || defined(__GNUC__)) && \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6816 |
(defined(__x86_64__) || defined(__i386__))) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6817 |
// with clang/gcc we can achieve the same effect on x86 by invoking int3 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6818 |
asm("int3"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6819 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6820 |
// Dereference nullptr through a volatile pointer to prevent the compiler |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6821 |
// from removing. We use this rather than abort() or __builtin_trap() for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6822 |
// portability: some debuggers don't correctly trap abort(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6823 |
*static_cast<volatile int*>(nullptr) = 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6824 |
#endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6825 |
} else if (GTEST_FLAG(throw_on_failure)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6826 |
#if GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6827 |
throw internal::GoogleTestFailureException(result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6828 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6829 |
// We cannot call abort() as it generates a pop-up in debug mode |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6830 |
// that cannot be suppressed in VC 7.1 or below. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6831 |
exit(1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6832 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6833 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6834 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6835 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6836 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6837 |
// Adds a TestProperty to the current TestResult object when invoked from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6838 |
// inside a test, to current TestSuite's ad_hoc_test_result_ when invoked |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6839 |
// from SetUpTestSuite or TearDownTestSuite, or to the global property set |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6840 |
// when invoked elsewhere. If the result already contains a property with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6841 |
// the same key, the value will be updated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6842 |
void UnitTest::RecordProperty(const std::string& key, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6843 |
const std::string& value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6844 |
impl_->RecordProperty(TestProperty(key, value)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6845 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6846 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6847 |
// Runs all tests in this UnitTest object and prints the result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6848 |
// Returns 0 if successful, or 1 otherwise. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6849 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6850 |
// We don't protect this under mutex_, as we only support calling it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6851 |
// from the main thread. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6852 |
int UnitTest::Run() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6853 |
const bool in_death_test_child_process = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6854 |
internal::GTEST_FLAG(internal_run_death_test).length() > 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6855 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6856 |
// Google Test implements this protocol for catching that a test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6857 |
// program exits before returning control to Google Test: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6858 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6859 |
// 1. Upon start, Google Test creates a file whose absolute path |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6860 |
// is specified by the environment variable |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6861 |
// TEST_PREMATURE_EXIT_FILE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6862 |
// 2. When Google Test has finished its work, it deletes the file. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6863 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6864 |
// This allows a test runner to set TEST_PREMATURE_EXIT_FILE before |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6865 |
// running a Google-Test-based test program and check the existence |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6866 |
// of the file at the end of the test execution to see if it has |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6867 |
// exited prematurely. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6868 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6869 |
// If we are in the child process of a death test, don't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6870 |
// create/delete the premature exit file, as doing so is unnecessary |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6871 |
// and will confuse the parent process. Otherwise, create/delete |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6872 |
// the file upon entering/leaving this function. If the program |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6873 |
// somehow exits before this function has a chance to return, the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6874 |
// premature-exit file will be left undeleted, causing a test runner |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6875 |
// that understands the premature-exit-file protocol to report the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6876 |
// test as having failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6877 |
const internal::ScopedPrematureExitFile premature_exit_file( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6878 |
in_death_test_child_process |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6879 |
? nullptr |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6880 |
: internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6881 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6882 |
// Captures the value of GTEST_FLAG(catch_exceptions). This value will be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6883 |
// used for the duration of the program. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6884 |
impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6885 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6886 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6887 |
// Either the user wants Google Test to catch exceptions thrown by the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6888 |
// tests or this is executing in the context of death test child |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6889 |
// process. In either case the user does not want to see pop-up dialogs |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6890 |
// about crashes - they are expected. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6891 |
if (impl()->catch_exceptions() || in_death_test_child_process) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6892 |
# if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6893 |
// SetErrorMode doesn't exist on CE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6894 |
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6895 |
SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6896 |
# endif // !GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6897 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6898 |
# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6899 |
// Death test children can be terminated with _abort(). On Windows, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6900 |
// _abort() can show a dialog with a warning message. This forces the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6901 |
// abort message to go to stderr instead. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6902 |
_set_error_mode(_OUT_TO_STDERR); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6903 |
# endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6904 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6905 |
# if defined(_MSC_VER) && !GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6906 |
// In the debug version, Visual Studio pops up a separate dialog |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6907 |
// offering a choice to debug the aborted program. We need to suppress |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6908 |
// this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6909 |
// executed. Google Test will notify the user of any unexpected |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6910 |
// failure via stderr. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6911 |
if (!GTEST_FLAG(break_on_failure)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6912 |
_set_abort_behavior( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6913 |
0x0, // Clear the following flags: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6914 |
_WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6915 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6916 |
// In debug mode, the Windows CRT can crash with an assertion over invalid |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6917 |
// input (e.g. passing an invalid file descriptor). The default handling |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6918 |
// for these assertions is to pop up a dialog and wait for user input. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6919 |
// Instead ask the CRT to dump such assertions to stderr non-interactively. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6920 |
if (!IsDebuggerPresent()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6921 |
(void)_CrtSetReportMode(_CRT_ASSERT, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6922 |
_CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6923 |
(void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6924 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6925 |
# endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6926 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6927 |
#endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6928 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6929 |
return internal::HandleExceptionsInMethodIfSupported( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6930 |
impl(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6931 |
&internal::UnitTestImpl::RunAllTests, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6932 |
"auxiliary test code (environments or event listeners)") ? 0 : 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6933 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6934 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6935 |
// Returns the working directory when the first TEST() or TEST_F() was |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6936 |
// executed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6937 |
const char* UnitTest::original_working_dir() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6938 |
return impl_->original_working_dir_.c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6939 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6940 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6941 |
// Returns the TestSuite object for the test that's currently running, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6942 |
// or NULL if no test is running. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6943 |
const TestSuite* UnitTest::current_test_suite() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6944 |
GTEST_LOCK_EXCLUDED_(mutex_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6945 |
internal::MutexLock lock(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6946 |
return impl_->current_test_suite(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6947 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6948 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6949 |
// Legacy API is still available but deprecated |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6950 |
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6951 |
const TestCase* UnitTest::current_test_case() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6952 |
GTEST_LOCK_EXCLUDED_(mutex_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6953 |
internal::MutexLock lock(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6954 |
return impl_->current_test_suite(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6955 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6956 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6957 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6958 |
// Returns the TestInfo object for the test that's currently running, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6959 |
// or NULL if no test is running. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6960 |
const TestInfo* UnitTest::current_test_info() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6961 |
GTEST_LOCK_EXCLUDED_(mutex_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6962 |
internal::MutexLock lock(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6963 |
return impl_->current_test_info(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6964 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6965 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6966 |
// Returns the random seed used at the start of the current test run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6967 |
int UnitTest::random_seed() const { return impl_->random_seed(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6968 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6969 |
// Returns ParameterizedTestSuiteRegistry object used to keep track of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6970 |
// value-parameterized tests and instantiate and register them. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6971 |
internal::ParameterizedTestSuiteRegistry& |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6972 |
UnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6973 |
return impl_->parameterized_test_registry(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6974 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6975 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6976 |
// Creates an empty UnitTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6977 |
UnitTest::UnitTest() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6978 |
impl_ = new internal::UnitTestImpl(this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6979 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6980 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6981 |
// Destructor of UnitTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6982 |
UnitTest::~UnitTest() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6983 |
delete impl_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6984 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6985 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6986 |
// Pushes a trace defined by SCOPED_TRACE() on to the per-thread |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6987 |
// Google Test trace stack. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6988 |
void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6989 |
GTEST_LOCK_EXCLUDED_(mutex_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6990 |
internal::MutexLock lock(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6991 |
impl_->gtest_trace_stack().push_back(trace); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6992 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6993 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6994 |
// Pops a trace from the per-thread Google Test trace stack. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6995 |
void UnitTest::PopGTestTrace() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6996 |
GTEST_LOCK_EXCLUDED_(mutex_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6997 |
internal::MutexLock lock(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6998 |
impl_->gtest_trace_stack().pop_back(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6999 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7000 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7001 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7002 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7003 |
UnitTestImpl::UnitTestImpl(UnitTest* parent) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7004 |
: parent_(parent), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7005 |
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7006 |
default_global_test_part_result_reporter_(this), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7007 |
default_per_thread_test_part_result_reporter_(this), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7008 |
GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_repoter_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7009 |
&default_global_test_part_result_reporter_), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7010 |
per_thread_test_part_result_reporter_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7011 |
&default_per_thread_test_part_result_reporter_), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7012 |
parameterized_test_registry_(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7013 |
parameterized_tests_registered_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7014 |
last_death_test_suite_(-1), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7015 |
current_test_suite_(nullptr), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7016 |
current_test_info_(nullptr), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7017 |
ad_hoc_test_result_(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7018 |
os_stack_trace_getter_(nullptr), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7019 |
post_flag_parse_init_performed_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7020 |
random_seed_(0), // Will be overridden by the flag before first use. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7021 |
random_(0), // Will be reseeded before first use. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7022 |
start_timestamp_(0), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7023 |
elapsed_time_(0), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7024 |
#if GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7025 |
death_test_factory_(new DefaultDeathTestFactory), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7026 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7027 |
// Will be overridden by the flag before first use. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7028 |
catch_exceptions_(false) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7029 |
listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7030 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7031 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7032 |
UnitTestImpl::~UnitTestImpl() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7033 |
// Deletes every TestSuite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7034 |
ForEach(test_suites_, internal::Delete<TestSuite>); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7035 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7036 |
// Deletes every Environment. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7037 |
ForEach(environments_, internal::Delete<Environment>); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7038 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7039 |
delete os_stack_trace_getter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7040 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7041 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7042 |
// Adds a TestProperty to the current TestResult object when invoked in a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7043 |
// context of a test, to current test suite's ad_hoc_test_result when invoke |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7044 |
// from SetUpTestSuite/TearDownTestSuite, or to the global property set |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7045 |
// otherwise. If the result already contains a property with the same key, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7046 |
// the value will be updated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7047 |
void UnitTestImpl::RecordProperty(const TestProperty& test_property) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7048 |
std::string xml_element; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7049 |
TestResult* test_result; // TestResult appropriate for property recording. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7050 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7051 |
if (current_test_info_ != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7052 |
xml_element = "testcase"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7053 |
test_result = &(current_test_info_->result_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7054 |
} else if (current_test_suite_ != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7055 |
xml_element = "testsuite"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7056 |
test_result = &(current_test_suite_->ad_hoc_test_result_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7057 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7058 |
xml_element = "testsuites"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7059 |
test_result = &ad_hoc_test_result_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7060 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7061 |
test_result->RecordProperty(xml_element, test_property); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7062 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7063 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7064 |
#if GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7065 |
// Disables event forwarding if the control is currently in a death test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7066 |
// subprocess. Must not be called before InitGoogleTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7067 |
void UnitTestImpl::SuppressTestEventsIfInSubprocess() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7068 |
if (internal_run_death_test_flag_.get() != nullptr) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7069 |
listeners()->SuppressEventForwarding(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7070 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7071 |
#endif // GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7072 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7073 |
// Initializes event listeners performing XML output as specified by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7074 |
// UnitTestOptions. Must not be called before InitGoogleTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7075 |
void UnitTestImpl::ConfigureXmlOutput() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7076 |
const std::string& output_format = UnitTestOptions::GetOutputFormat(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7077 |
if (output_format == "xml") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7078 |
listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7079 |
UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7080 |
} else if (output_format == "json") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7081 |
listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7082 |
UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7083 |
} else if (output_format != "") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7084 |
GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \"" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7085 |
<< output_format << "\" ignored."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7086 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7087 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7088 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7089 |
#if GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7090 |
// Initializes event listeners for streaming test results in string form. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7091 |
// Must not be called before InitGoogleTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7092 |
void UnitTestImpl::ConfigureStreamingOutput() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7093 |
const std::string& target = GTEST_FLAG(stream_result_to); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7094 |
if (!target.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7095 |
const size_t pos = target.find(':'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7096 |
if (pos != std::string::npos) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7097 |
listeners()->Append(new StreamingListener(target.substr(0, pos), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7098 |
target.substr(pos+1))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7099 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7100 |
GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7101 |
<< "\" ignored."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7102 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7103 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7104 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7105 |
#endif // GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7106 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7107 |
// Performs initialization dependent upon flag values obtained in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7108 |
// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7109 |
// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7110 |
// this function is also called from RunAllTests. Since this function can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7111 |
// called more than once, it has to be idempotent. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7112 |
void UnitTestImpl::PostFlagParsingInit() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7113 |
// Ensures that this function does not execute more than once. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7114 |
if (!post_flag_parse_init_performed_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7115 |
post_flag_parse_init_performed_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7116 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7117 |
#if defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7118 |
// Register to send notifications about key process state changes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7119 |
listeners()->Append(new GTEST_CUSTOM_TEST_EVENT_LISTENER_()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7120 |
#endif // defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7121 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7122 |
#if GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7123 |
InitDeathTestSubprocessControlInfo(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7124 |
SuppressTestEventsIfInSubprocess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7125 |
#endif // GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7126 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7127 |
// Registers parameterized tests. This makes parameterized tests |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7128 |
// available to the UnitTest reflection API without running |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7129 |
// RUN_ALL_TESTS. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7130 |
RegisterParameterizedTests(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7131 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7132 |
// Configures listeners for XML output. This makes it possible for users |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7133 |
// to shut down the default XML output before invoking RUN_ALL_TESTS. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7134 |
ConfigureXmlOutput(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7135 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7136 |
if (GTEST_FLAG(brief)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7137 |
listeners()->SetDefaultResultPrinter(new BriefUnitTestResultPrinter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7138 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7139 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7140 |
#if GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7141 |
// Configures listeners for streaming test results to the specified server. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7142 |
ConfigureStreamingOutput(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7143 |
#endif // GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7144 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7145 |
#if GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7146 |
if (GTEST_FLAG(install_failure_signal_handler)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7147 |
absl::FailureSignalHandlerOptions options; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7148 |
absl::InstallFailureSignalHandler(options); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7149 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7150 |
#endif // GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7151 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7152 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7153 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7154 |
// A predicate that checks the name of a TestSuite against a known |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7155 |
// value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7156 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7157 |
// This is used for implementation of the UnitTest class only. We put |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7158 |
// it in the anonymous namespace to prevent polluting the outer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7159 |
// namespace. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7160 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7161 |
// TestSuiteNameIs is copyable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7162 |
class TestSuiteNameIs { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7163 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7164 |
// Constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7165 |
explicit TestSuiteNameIs(const std::string& name) : name_(name) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7166 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7167 |
// Returns true if and only if the name of test_suite matches name_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7168 |
bool operator()(const TestSuite* test_suite) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7169 |
return test_suite != nullptr && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7170 |
strcmp(test_suite->name(), name_.c_str()) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7171 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7172 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7173 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7174 |
std::string name_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7175 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7176 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7177 |
// Finds and returns a TestSuite with the given name. If one doesn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7178 |
// exist, creates one and returns it. It's the CALLER'S |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7179 |
// RESPONSIBILITY to ensure that this function is only called WHEN THE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7180 |
// TESTS ARE NOT SHUFFLED. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7181 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7182 |
// Arguments: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7183 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7184 |
// test_suite_name: name of the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7185 |
// type_param: the name of the test suite's type parameter, or NULL if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7186 |
// this is not a typed or a type-parameterized test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7187 |
// set_up_tc: pointer to the function that sets up the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7188 |
// tear_down_tc: pointer to the function that tears down the test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7189 |
TestSuite* UnitTestImpl::GetTestSuite( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7190 |
const char* test_suite_name, const char* type_param, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7191 |
internal::SetUpTestSuiteFunc set_up_tc, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7192 |
internal::TearDownTestSuiteFunc tear_down_tc) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7193 |
// Can we find a TestSuite with the given name? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7194 |
const auto test_suite = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7195 |
std::find_if(test_suites_.rbegin(), test_suites_.rend(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7196 |
TestSuiteNameIs(test_suite_name)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7197 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7198 |
if (test_suite != test_suites_.rend()) return *test_suite; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7199 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7200 |
// No. Let's create one. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7201 |
auto* const new_test_suite = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7202 |
new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7203 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7204 |
// Is this a death test suite? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7205 |
if (internal::UnitTestOptions::MatchesFilter(test_suite_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7206 |
kDeathTestSuiteFilter)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7207 |
// Yes. Inserts the test suite after the last death test suite |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7208 |
// defined so far. This only works when the test suites haven't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7209 |
// been shuffled. Otherwise we may end up running a death test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7210 |
// after a non-death test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7211 |
++last_death_test_suite_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7212 |
test_suites_.insert(test_suites_.begin() + last_death_test_suite_, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7213 |
new_test_suite); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7214 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7215 |
// No. Appends to the end of the list. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7216 |
test_suites_.push_back(new_test_suite); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7217 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7218 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7219 |
test_suite_indices_.push_back(static_cast<int>(test_suite_indices_.size())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7220 |
return new_test_suite; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7221 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7222 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7223 |
// Helpers for setting up / tearing down the given environment. They |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7224 |
// are for use in the ForEach() function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7225 |
static void SetUpEnvironment(Environment* env) { env->SetUp(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7226 |
static void TearDownEnvironment(Environment* env) { env->TearDown(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7227 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7228 |
// Runs all tests in this UnitTest object, prints the result, and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7229 |
// returns true if all tests are successful. If any exception is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7230 |
// thrown during a test, the test is considered to be failed, but the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7231 |
// rest of the tests will still be run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7232 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7233 |
// When parameterized tests are enabled, it expands and registers |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7234 |
// parameterized tests first in RegisterParameterizedTests(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7235 |
// All other functions called from RunAllTests() may safely assume that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7236 |
// parameterized tests are ready to be counted and run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7237 |
bool UnitTestImpl::RunAllTests() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7238 |
// True if and only if Google Test is initialized before RUN_ALL_TESTS() is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7239 |
// called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7240 |
const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7241 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7242 |
// Do not run any test if the --help flag was specified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7243 |
if (g_help_flag) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7244 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7245 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7246 |
// Repeats the call to the post-flag parsing initialization in case the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7247 |
// user didn't call InitGoogleTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7248 |
PostFlagParsingInit(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7249 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7250 |
// Even if sharding is not on, test runners may want to use the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7251 |
// GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7252 |
// protocol. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7253 |
internal::WriteToShardStatusFileIfNeeded(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7254 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7255 |
// True if and only if we are in a subprocess for running a thread-safe-style |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7256 |
// death test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7257 |
bool in_subprocess_for_death_test = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7258 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7259 |
#if GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7260 |
in_subprocess_for_death_test = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7261 |
(internal_run_death_test_flag_.get() != nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7262 |
# if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7263 |
if (in_subprocess_for_death_test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7264 |
GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7265 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7266 |
# endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7267 |
#endif // GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7268 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7269 |
const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7270 |
in_subprocess_for_death_test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7271 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7272 |
// Compares the full test names with the filter to decide which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7273 |
// tests to run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7274 |
const bool has_tests_to_run = FilterTests(should_shard |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7275 |
? HONOR_SHARDING_PROTOCOL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7276 |
: IGNORE_SHARDING_PROTOCOL) > 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7277 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7278 |
// Lists the tests and exits if the --gtest_list_tests flag was specified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7279 |
if (GTEST_FLAG(list_tests)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7280 |
// This must be called *after* FilterTests() has been called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7281 |
ListTestsMatchingFilter(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7282 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7283 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7284 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7285 |
random_seed_ = GTEST_FLAG(shuffle) ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7286 |
GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7287 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7288 |
// True if and only if at least one test has failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7289 |
bool failed = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7290 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7291 |
TestEventListener* repeater = listeners()->repeater(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7292 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7293 |
start_timestamp_ = GetTimeInMillis(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7294 |
repeater->OnTestProgramStart(*parent_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7295 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7296 |
// How many times to repeat the tests? We don't want to repeat them |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7297 |
// when we are inside the subprocess of a death test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7298 |
const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7299 |
// Repeats forever if the repeat count is negative. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7300 |
const bool gtest_repeat_forever = repeat < 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7301 |
for (int i = 0; gtest_repeat_forever || i != repeat; i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7302 |
// We want to preserve failures generated by ad-hoc test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7303 |
// assertions executed before RUN_ALL_TESTS(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7304 |
ClearNonAdHocTestResult(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7305 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7306 |
Timer timer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7307 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7308 |
// Shuffles test suites and tests if requested. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7309 |
if (has_tests_to_run && GTEST_FLAG(shuffle)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7310 |
random()->Reseed(static_cast<uint32_t>(random_seed_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7311 |
// This should be done before calling OnTestIterationStart(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7312 |
// such that a test event listener can see the actual test order |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7313 |
// in the event. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7314 |
ShuffleTests(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7315 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7316 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7317 |
// Tells the unit test event listeners that the tests are about to start. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7318 |
repeater->OnTestIterationStart(*parent_, i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7319 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7320 |
// Runs each test suite if there is at least one test to run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7321 |
if (has_tests_to_run) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7322 |
// Sets up all environments beforehand. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7323 |
repeater->OnEnvironmentsSetUpStart(*parent_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7324 |
ForEach(environments_, SetUpEnvironment); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7325 |
repeater->OnEnvironmentsSetUpEnd(*parent_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7326 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7327 |
// Runs the tests only if there was no fatal failure or skip triggered |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7328 |
// during global set-up. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7329 |
if (Test::IsSkipped()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7330 |
// Emit diagnostics when global set-up calls skip, as it will not be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7331 |
// emitted by default. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7332 |
TestResult& test_result = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7333 |
*internal::GetUnitTestImpl()->current_test_result(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7334 |
for (int j = 0; j < test_result.total_part_count(); ++j) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7335 |
const TestPartResult& test_part_result = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7336 |
test_result.GetTestPartResult(j); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7337 |
if (test_part_result.type() == TestPartResult::kSkip) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7338 |
const std::string& result = test_part_result.message(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7339 |
printf("%s\n", result.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7340 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7341 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7342 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7343 |
} else if (!Test::HasFatalFailure()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7344 |
for (int test_index = 0; test_index < total_test_suite_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7345 |
test_index++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7346 |
GetMutableSuiteCase(test_index)->Run(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7347 |
if (GTEST_FLAG(fail_fast) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7348 |
GetMutableSuiteCase(test_index)->Failed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7349 |
for (int j = test_index + 1; j < total_test_suite_count(); j++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7350 |
GetMutableSuiteCase(j)->Skip(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7351 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7352 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7353 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7354 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7355 |
} else if (Test::HasFatalFailure()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7356 |
// If there was a fatal failure during the global setup then we know we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7357 |
// aren't going to run any tests. Explicitly mark all of the tests as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7358 |
// skipped to make this obvious in the output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7359 |
for (int test_index = 0; test_index < total_test_suite_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7360 |
test_index++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7361 |
GetMutableSuiteCase(test_index)->Skip(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7362 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7363 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7364 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7365 |
// Tears down all environments in reverse order afterwards. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7366 |
repeater->OnEnvironmentsTearDownStart(*parent_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7367 |
std::for_each(environments_.rbegin(), environments_.rend(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7368 |
TearDownEnvironment); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7369 |
repeater->OnEnvironmentsTearDownEnd(*parent_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7370 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7371 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7372 |
elapsed_time_ = timer.Elapsed(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7373 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7374 |
// Tells the unit test event listener that the tests have just finished. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7375 |
repeater->OnTestIterationEnd(*parent_, i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7376 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7377 |
// Gets the result and clears it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7378 |
if (!Passed()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7379 |
failed = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7380 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7381 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7382 |
// Restores the original test order after the iteration. This |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7383 |
// allows the user to quickly repro a failure that happens in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7384 |
// N-th iteration without repeating the first (N - 1) iterations. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7385 |
// This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7386 |
// case the user somehow changes the value of the flag somewhere |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7387 |
// (it's always safe to unshuffle the tests). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7388 |
UnshuffleTests(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7389 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7390 |
if (GTEST_FLAG(shuffle)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7391 |
// Picks a new random seed for each iteration. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7392 |
random_seed_ = GetNextRandomSeed(random_seed_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7393 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7394 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7395 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7396 |
repeater->OnTestProgramEnd(*parent_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7397 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7398 |
if (!gtest_is_initialized_before_run_all_tests) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7399 |
ColoredPrintf( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7400 |
GTestColor::kRed, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7401 |
"\nIMPORTANT NOTICE - DO NOT IGNORE:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7402 |
"This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7403 |
"() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7404 |
" will start to enforce the valid usage. " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7405 |
"Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7406 |
#if GTEST_FOR_GOOGLE_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7407 |
ColoredPrintf(GTestColor::kRed, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7408 |
"For more details, see http://wiki/Main/ValidGUnitMain.\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7409 |
#endif // GTEST_FOR_GOOGLE_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7410 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7411 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7412 |
return !failed; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7413 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7414 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7415 |
// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7416 |
// if the variable is present. If a file already exists at this location, this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7417 |
// function will write over it. If the variable is present, but the file cannot |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7418 |
// be created, prints an error and exits. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7419 |
void WriteToShardStatusFileIfNeeded() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7420 |
const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7421 |
if (test_shard_file != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7422 |
FILE* const file = posix::FOpen(test_shard_file, "w"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7423 |
if (file == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7424 |
ColoredPrintf(GTestColor::kRed, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7425 |
"Could not write to the test shard status file \"%s\" " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7426 |
"specified by the %s environment variable.\n", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7427 |
test_shard_file, kTestShardStatusFile); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7428 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7429 |
exit(EXIT_FAILURE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7430 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7431 |
fclose(file); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7432 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7433 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7434 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7435 |
// Checks whether sharding is enabled by examining the relevant |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7436 |
// environment variable values. If the variables are present, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7437 |
// but inconsistent (i.e., shard_index >= total_shards), prints |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7438 |
// an error and exits. If in_subprocess_for_death_test, sharding is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7439 |
// disabled because it must only be applied to the original test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7440 |
// process. Otherwise, we could filter out death tests we intended to execute. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7441 |
bool ShouldShard(const char* total_shards_env, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7442 |
const char* shard_index_env, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7443 |
bool in_subprocess_for_death_test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7444 |
if (in_subprocess_for_death_test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7445 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7446 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7447 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7448 |
const int32_t total_shards = Int32FromEnvOrDie(total_shards_env, -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7449 |
const int32_t shard_index = Int32FromEnvOrDie(shard_index_env, -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7450 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7451 |
if (total_shards == -1 && shard_index == -1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7452 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7453 |
} else if (total_shards == -1 && shard_index != -1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7454 |
const Message msg = Message() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7455 |
<< "Invalid environment variables: you have " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7456 |
<< kTestShardIndex << " = " << shard_index |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7457 |
<< ", but have left " << kTestTotalShards << " unset.\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7458 |
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7459 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7460 |
exit(EXIT_FAILURE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7461 |
} else if (total_shards != -1 && shard_index == -1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7462 |
const Message msg = Message() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7463 |
<< "Invalid environment variables: you have " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7464 |
<< kTestTotalShards << " = " << total_shards |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7465 |
<< ", but have left " << kTestShardIndex << " unset.\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7466 |
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7467 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7468 |
exit(EXIT_FAILURE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7469 |
} else if (shard_index < 0 || shard_index >= total_shards) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7470 |
const Message msg = Message() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7471 |
<< "Invalid environment variables: we require 0 <= " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7472 |
<< kTestShardIndex << " < " << kTestTotalShards |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7473 |
<< ", but you have " << kTestShardIndex << "=" << shard_index |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7474 |
<< ", " << kTestTotalShards << "=" << total_shards << ".\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7475 |
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7476 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7477 |
exit(EXIT_FAILURE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7478 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7479 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7480 |
return total_shards > 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7481 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7482 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7483 |
// Parses the environment variable var as an Int32. If it is unset, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7484 |
// returns default_val. If it is not an Int32, prints an error |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7485 |
// and aborts. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7486 |
int32_t Int32FromEnvOrDie(const char* var, int32_t default_val) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7487 |
const char* str_val = posix::GetEnv(var); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7488 |
if (str_val == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7489 |
return default_val; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7490 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7491 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7492 |
int32_t result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7493 |
if (!ParseInt32(Message() << "The value of environment variable " << var, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7494 |
str_val, &result)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7495 |
exit(EXIT_FAILURE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7496 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7497 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7498 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7499 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7500 |
// Given the total number of shards, the shard index, and the test id, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7501 |
// returns true if and only if the test should be run on this shard. The test id |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7502 |
// is some arbitrary but unique non-negative integer assigned to each test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7503 |
// method. Assumes that 0 <= shard_index < total_shards. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7504 |
bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7505 |
return (test_id % total_shards) == shard_index; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7506 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7507 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7508 |
// Compares the name of each test with the user-specified filter to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7509 |
// decide whether the test should be run, then records the result in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7510 |
// each TestSuite and TestInfo object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7511 |
// If shard_tests == true, further filters tests based on sharding |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7512 |
// variables in the environment - see |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7513 |
// https://github.com/google/googletest/blob/master/googletest/docs/advanced.md |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7514 |
// . Returns the number of tests that should run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7515 |
int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7516 |
const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7517 |
Int32FromEnvOrDie(kTestTotalShards, -1) : -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7518 |
const int32_t shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7519 |
Int32FromEnvOrDie(kTestShardIndex, -1) : -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7520 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7521 |
// num_runnable_tests are the number of tests that will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7522 |
// run across all shards (i.e., match filter and are not disabled). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7523 |
// num_selected_tests are the number of tests to be run on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7524 |
// this shard. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7525 |
int num_runnable_tests = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7526 |
int num_selected_tests = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7527 |
for (auto* test_suite : test_suites_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7528 |
const std::string& test_suite_name = test_suite->name(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7529 |
test_suite->set_should_run(false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7530 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7531 |
for (size_t j = 0; j < test_suite->test_info_list().size(); j++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7532 |
TestInfo* const test_info = test_suite->test_info_list()[j]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7533 |
const std::string test_name(test_info->name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7534 |
// A test is disabled if test suite name or test name matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7535 |
// kDisableTestFilter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7536 |
const bool is_disabled = internal::UnitTestOptions::MatchesFilter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7537 |
test_suite_name, kDisableTestFilter) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7538 |
internal::UnitTestOptions::MatchesFilter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7539 |
test_name, kDisableTestFilter); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7540 |
test_info->is_disabled_ = is_disabled; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7541 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7542 |
const bool matches_filter = internal::UnitTestOptions::FilterMatchesTest( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7543 |
test_suite_name, test_name); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7544 |
test_info->matches_filter_ = matches_filter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7545 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7546 |
const bool is_runnable = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7547 |
(GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7548 |
matches_filter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7549 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7550 |
const bool is_in_another_shard = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7551 |
shard_tests != IGNORE_SHARDING_PROTOCOL && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7552 |
!ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7553 |
test_info->is_in_another_shard_ = is_in_another_shard; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7554 |
const bool is_selected = is_runnable && !is_in_another_shard; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7555 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7556 |
num_runnable_tests += is_runnable; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7557 |
num_selected_tests += is_selected; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7558 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7559 |
test_info->should_run_ = is_selected; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7560 |
test_suite->set_should_run(test_suite->should_run() || is_selected); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7561 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7562 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7563 |
return num_selected_tests; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7564 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7565 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7566 |
// Prints the given C-string on a single line by replacing all '\n' |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7567 |
// characters with string "\\n". If the output takes more than |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7568 |
// max_length characters, only prints the first max_length characters |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7569 |
// and "...". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7570 |
static void PrintOnOneLine(const char* str, int max_length) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7571 |
if (str != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7572 |
for (int i = 0; *str != '\0'; ++str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7573 |
if (i >= max_length) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7574 |
printf("..."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7575 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7576 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7577 |
if (*str == '\n') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7578 |
printf("\\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7579 |
i += 2; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7580 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7581 |
printf("%c", *str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7582 |
++i; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7583 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7584 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7585 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7586 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7587 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7588 |
// Prints the names of the tests matching the user-specified filter flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7589 |
void UnitTestImpl::ListTestsMatchingFilter() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7590 |
// Print at most this many characters for each type/value parameter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7591 |
const int kMaxParamLength = 250; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7592 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7593 |
for (auto* test_suite : test_suites_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7594 |
bool printed_test_suite_name = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7595 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7596 |
for (size_t j = 0; j < test_suite->test_info_list().size(); j++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7597 |
const TestInfo* const test_info = test_suite->test_info_list()[j]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7598 |
if (test_info->matches_filter_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7599 |
if (!printed_test_suite_name) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7600 |
printed_test_suite_name = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7601 |
printf("%s.", test_suite->name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7602 |
if (test_suite->type_param() != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7603 |
printf(" # %s = ", kTypeParamLabel); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7604 |
// We print the type parameter on a single line to make |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7605 |
// the output easy to parse by a program. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7606 |
PrintOnOneLine(test_suite->type_param(), kMaxParamLength); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7607 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7608 |
printf("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7609 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7610 |
printf(" %s", test_info->name()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7611 |
if (test_info->value_param() != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7612 |
printf(" # %s = ", kValueParamLabel); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7613 |
// We print the value parameter on a single line to make the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7614 |
// output easy to parse by a program. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7615 |
PrintOnOneLine(test_info->value_param(), kMaxParamLength); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7616 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7617 |
printf("\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7618 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7619 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7620 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7621 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7622 |
const std::string& output_format = UnitTestOptions::GetOutputFormat(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7623 |
if (output_format == "xml" || output_format == "json") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7624 |
FILE* fileout = OpenFileForWriting( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7625 |
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7626 |
std::stringstream stream; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7627 |
if (output_format == "xml") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7628 |
XmlUnitTestResultPrinter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7629 |
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7630 |
.PrintXmlTestsList(&stream, test_suites_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7631 |
} else if (output_format == "json") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7632 |
JsonUnitTestResultPrinter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7633 |
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7634 |
.PrintJsonTestList(&stream, test_suites_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7635 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7636 |
fprintf(fileout, "%s", StringStreamToString(&stream).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7637 |
fclose(fileout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7638 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7639 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7640 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7641 |
// Sets the OS stack trace getter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7642 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7643 |
// Does nothing if the input and the current OS stack trace getter are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7644 |
// the same; otherwise, deletes the old getter and makes the input the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7645 |
// current getter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7646 |
void UnitTestImpl::set_os_stack_trace_getter( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7647 |
OsStackTraceGetterInterface* getter) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7648 |
if (os_stack_trace_getter_ != getter) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7649 |
delete os_stack_trace_getter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7650 |
os_stack_trace_getter_ = getter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7651 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7652 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7653 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7654 |
// Returns the current OS stack trace getter if it is not NULL; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7655 |
// otherwise, creates an OsStackTraceGetter, makes it the current |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7656 |
// getter, and returns it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7657 |
OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7658 |
if (os_stack_trace_getter_ == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7659 |
#ifdef GTEST_OS_STACK_TRACE_GETTER_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7660 |
os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7661 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7662 |
os_stack_trace_getter_ = new OsStackTraceGetter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7663 |
#endif // GTEST_OS_STACK_TRACE_GETTER_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7664 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7665 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7666 |
return os_stack_trace_getter_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7667 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7668 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7669 |
// Returns the most specific TestResult currently running. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7670 |
TestResult* UnitTestImpl::current_test_result() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7671 |
if (current_test_info_ != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7672 |
return ¤t_test_info_->result_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7673 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7674 |
if (current_test_suite_ != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7675 |
return ¤t_test_suite_->ad_hoc_test_result_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7676 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7677 |
return &ad_hoc_test_result_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7678 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7679 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7680 |
// Shuffles all test suites, and the tests within each test suite, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7681 |
// making sure that death tests are still run first. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7682 |
void UnitTestImpl::ShuffleTests() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7683 |
// Shuffles the death test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7684 |
ShuffleRange(random(), 0, last_death_test_suite_ + 1, &test_suite_indices_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7685 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7686 |
// Shuffles the non-death test suites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7687 |
ShuffleRange(random(), last_death_test_suite_ + 1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7688 |
static_cast<int>(test_suites_.size()), &test_suite_indices_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7689 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7690 |
// Shuffles the tests inside each test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7691 |
for (auto& test_suite : test_suites_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7692 |
test_suite->ShuffleTests(random()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7693 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7694 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7695 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7696 |
// Restores the test suites and tests to their order before the first shuffle. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7697 |
void UnitTestImpl::UnshuffleTests() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7698 |
for (size_t i = 0; i < test_suites_.size(); i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7699 |
// Unshuffles the tests in each test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7700 |
test_suites_[i]->UnshuffleTests(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7701 |
// Resets the index of each test suite. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7702 |
test_suite_indices_[i] = static_cast<int>(i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7703 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7704 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7705 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7706 |
// Returns the current OS stack trace as an std::string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7707 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7708 |
// The maximum number of stack frames to be included is specified by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7709 |
// the gtest_stack_trace_depth flag. The skip_count parameter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7710 |
// specifies the number of top frames to be skipped, which doesn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7711 |
// count against the number of frames to be included. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7712 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7713 |
// For example, if Foo() calls Bar(), which in turn calls |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7714 |
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7715 |
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7716 |
std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7717 |
int skip_count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7718 |
// We pass skip_count + 1 to skip this wrapper function in addition |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7719 |
// to what the user really wants to skip. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7720 |
return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7721 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7722 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7723 |
// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7724 |
// suppress unreachable code warnings. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7725 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7726 |
class ClassUniqueToAlwaysTrue {}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7727 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7728 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7729 |
bool IsTrue(bool condition) { return condition; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7730 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7731 |
bool AlwaysTrue() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7732 |
#if GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7733 |
// This condition is always false so AlwaysTrue() never actually throws, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7734 |
// but it makes the compiler think that it may throw. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7735 |
if (IsTrue(false)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7736 |
throw ClassUniqueToAlwaysTrue(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7737 |
#endif // GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7738 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7739 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7740 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7741 |
// If *pstr starts with the given prefix, modifies *pstr to be right |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7742 |
// past the prefix and returns true; otherwise leaves *pstr unchanged |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7743 |
// and returns false. None of pstr, *pstr, and prefix can be NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7744 |
bool SkipPrefix(const char* prefix, const char** pstr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7745 |
const size_t prefix_len = strlen(prefix); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7746 |
if (strncmp(*pstr, prefix, prefix_len) == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7747 |
*pstr += prefix_len; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7748 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7749 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7750 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7751 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7752 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7753 |
// Parses a string as a command line flag. The string should have |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7754 |
// the format "--flag=value". When def_optional is true, the "=value" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7755 |
// part can be omitted. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7756 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7757 |
// Returns the value of the flag, or NULL if the parsing failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7758 |
static const char* ParseFlagValue(const char* str, const char* flag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7759 |
bool def_optional) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7760 |
// str and flag must not be NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7761 |
if (str == nullptr || flag == nullptr) return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7762 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7763 |
// The flag must start with "--" followed by GTEST_FLAG_PREFIX_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7764 |
const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7765 |
const size_t flag_len = flag_str.length(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7766 |
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7767 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7768 |
// Skips the flag name. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7769 |
const char* flag_end = str + flag_len; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7770 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7771 |
// When def_optional is true, it's OK to not have a "=value" part. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7772 |
if (def_optional && (flag_end[0] == '\0')) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7773 |
return flag_end; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7774 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7775 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7776 |
// If def_optional is true and there are more characters after the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7777 |
// flag name, or if def_optional is false, there must be a '=' after |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7778 |
// the flag name. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7779 |
if (flag_end[0] != '=') return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7780 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7781 |
// Returns the string after "=". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7782 |
return flag_end + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7783 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7784 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7785 |
// Parses a string for a bool flag, in the form of either |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7786 |
// "--flag=value" or "--flag". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7787 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7788 |
// In the former case, the value is taken as true as long as it does |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7789 |
// not start with '0', 'f', or 'F'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7790 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7791 |
// In the latter case, the value is taken as true. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7792 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7793 |
// On success, stores the value of the flag in *value, and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7794 |
// true. On failure, returns false without changing *value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7795 |
static bool ParseBoolFlag(const char* str, const char* flag, bool* value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7796 |
// Gets the value of the flag as a string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7797 |
const char* const value_str = ParseFlagValue(str, flag, true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7798 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7799 |
// Aborts if the parsing failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7800 |
if (value_str == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7801 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7802 |
// Converts the string value to a bool. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7803 |
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7804 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7805 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7806 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7807 |
// Parses a string for an int32_t flag, in the form of "--flag=value". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7808 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7809 |
// On success, stores the value of the flag in *value, and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7810 |
// true. On failure, returns false without changing *value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7811 |
bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7812 |
// Gets the value of the flag as a string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7813 |
const char* const value_str = ParseFlagValue(str, flag, false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7814 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7815 |
// Aborts if the parsing failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7816 |
if (value_str == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7817 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7818 |
// Sets *value to the value of the flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7819 |
return ParseInt32(Message() << "The value of flag --" << flag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7820 |
value_str, value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7821 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7822 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7823 |
// Parses a string for a string flag, in the form of "--flag=value". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7824 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7825 |
// On success, stores the value of the flag in *value, and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7826 |
// true. On failure, returns false without changing *value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7827 |
template <typename String> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7828 |
static bool ParseStringFlag(const char* str, const char* flag, String* value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7829 |
// Gets the value of the flag as a string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7830 |
const char* const value_str = ParseFlagValue(str, flag, false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7831 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7832 |
// Aborts if the parsing failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7833 |
if (value_str == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7834 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7835 |
// Sets *value to the value of the flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7836 |
*value = value_str; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7837 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7838 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7839 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7840 |
// Determines whether a string has a prefix that Google Test uses for its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7841 |
// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7842 |
// If Google Test detects that a command line flag has its prefix but is not |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7843 |
// recognized, it will print its help message. Flags starting with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7844 |
// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7845 |
// internal flags and do not trigger the help message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7846 |
static bool HasGoogleTestFlagPrefix(const char* str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7847 |
return (SkipPrefix("--", &str) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7848 |
SkipPrefix("-", &str) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7849 |
SkipPrefix("/", &str)) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7850 |
!SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7851 |
(SkipPrefix(GTEST_FLAG_PREFIX_, &str) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7852 |
SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7853 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7854 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7855 |
// Prints a string containing code-encoded text. The following escape |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7856 |
// sequences can be used in the string to control the text color: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7857 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7858 |
// @@ prints a single '@' character. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7859 |
// @R changes the color to red. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7860 |
// @G changes the color to green. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7861 |
// @Y changes the color to yellow. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7862 |
// @D changes to the default terminal text color. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7863 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7864 |
static void PrintColorEncoded(const char* str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7865 |
GTestColor color = GTestColor::kDefault; // The current color. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7866 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7867 |
// Conceptually, we split the string into segments divided by escape |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7868 |
// sequences. Then we print one segment at a time. At the end of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7869 |
// each iteration, the str pointer advances to the beginning of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7870 |
// next segment. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7871 |
for (;;) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7872 |
const char* p = strchr(str, '@'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7873 |
if (p == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7874 |
ColoredPrintf(color, "%s", str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7875 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7876 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7877 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7878 |
ColoredPrintf(color, "%s", std::string(str, p).c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7879 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7880 |
const char ch = p[1]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7881 |
str = p + 2; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7882 |
if (ch == '@') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7883 |
ColoredPrintf(color, "@"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7884 |
} else if (ch == 'D') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7885 |
color = GTestColor::kDefault; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7886 |
} else if (ch == 'R') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7887 |
color = GTestColor::kRed; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7888 |
} else if (ch == 'G') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7889 |
color = GTestColor::kGreen; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7890 |
} else if (ch == 'Y') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7891 |
color = GTestColor::kYellow; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7892 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7893 |
--str; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7894 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7895 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7896 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7897 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7898 |
static const char kColorEncodedHelpMessage[] = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7899 |
"This program contains tests written using " GTEST_NAME_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7900 |
". You can use the\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7901 |
"following command line flags to control its behavior:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7902 |
"\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7903 |
"Test Selection:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7904 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7905 |
"list_tests@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7906 |
" List the names of all tests instead of running them. The name of\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7907 |
" TEST(Foo, Bar) is \"Foo.Bar\".\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7908 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7909 |
"filter=@YPOSITIVE_PATTERNS" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7910 |
"[@G-@YNEGATIVE_PATTERNS]@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7911 |
" Run only the tests whose name matches one of the positive patterns " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7912 |
"but\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7913 |
" none of the negative patterns. '?' matches any single character; " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7914 |
"'*'\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7915 |
" matches any substring; ':' separates two patterns.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7916 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7917 |
"also_run_disabled_tests@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7918 |
" Run all disabled tests too.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7919 |
"\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7920 |
"Test Execution:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7921 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7922 |
"repeat=@Y[COUNT]@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7923 |
" Run the tests repeatedly; use a negative count to repeat forever.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7924 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7925 |
"shuffle@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7926 |
" Randomize tests' orders on every iteration.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7927 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7928 |
"random_seed=@Y[NUMBER]@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7929 |
" Random number seed to use for shuffling test orders (between 1 and\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7930 |
" 99999, or 0 to use a seed based on the current time).\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7931 |
"\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7932 |
"Test Output:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7933 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7934 |
"color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7935 |
" Enable/disable colored output. The default is @Gauto@D.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7936 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7937 |
"brief=1@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7938 |
" Only print test failures.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7939 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7940 |
"print_time=0@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7941 |
" Don't print the elapsed time of each test.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7942 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7943 |
"output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7944 |
"@Y|@G:@YFILE_PATH]@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7945 |
" Generate a JSON or XML report in the given directory or with the " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7946 |
"given\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7947 |
" file name. @YFILE_PATH@D defaults to @Gtest_detail.xml@D.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7948 |
# if GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7949 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7950 |
"stream_result_to=@YHOST@G:@YPORT@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7951 |
" Stream test results to the given server.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7952 |
# endif // GTEST_CAN_STREAM_RESULTS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7953 |
"\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7954 |
"Assertion Behavior:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7955 |
# if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7956 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7957 |
"death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7958 |
" Set the default death test style.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7959 |
# endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7960 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7961 |
"break_on_failure@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7962 |
" Turn assertion failures into debugger break-points.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7963 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7964 |
"throw_on_failure@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7965 |
" Turn assertion failures into C++ exceptions for use by an external\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7966 |
" test framework.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7967 |
" @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7968 |
"catch_exceptions=0@D\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7969 |
" Do not report exceptions as test failures. Instead, allow them\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7970 |
" to crash the program or throw a pop-up (on Windows).\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7971 |
"\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7972 |
"Except for @G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7973 |
"list_tests@D, you can alternatively set " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7974 |
"the corresponding\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7975 |
"environment variable of a flag (all letters in upper-case). For example, " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7976 |
"to\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7977 |
"disable colored text output, you can either specify " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7978 |
"@G--" GTEST_FLAG_PREFIX_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7979 |
"color=no@D or set\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7980 |
"the @G" GTEST_FLAG_PREFIX_UPPER_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7981 |
"COLOR@D environment variable to @Gno@D.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7982 |
"\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7983 |
"For more information, please read the " GTEST_NAME_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7984 |
" documentation at\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7985 |
"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7986 |
"\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7987 |
"(not one in your own code or tests), please report it to\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7988 |
"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7989 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7990 |
static bool ParseGoogleTestFlag(const char* const arg) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7991 |
return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7992 |
>EST_FLAG(also_run_disabled_tests)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7993 |
ParseBoolFlag(arg, kBreakOnFailureFlag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7994 |
>EST_FLAG(break_on_failure)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7995 |
ParseBoolFlag(arg, kCatchExceptionsFlag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7996 |
>EST_FLAG(catch_exceptions)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7997 |
ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7998 |
ParseStringFlag(arg, kDeathTestStyleFlag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7999 |
>EST_FLAG(death_test_style)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8000 |
ParseBoolFlag(arg, kDeathTestUseFork, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8001 |
>EST_FLAG(death_test_use_fork)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8002 |
ParseBoolFlag(arg, kFailFast, >EST_FLAG(fail_fast)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8003 |
ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8004 |
ParseStringFlag(arg, kInternalRunDeathTestFlag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8005 |
>EST_FLAG(internal_run_death_test)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8006 |
ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8007 |
ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8008 |
ParseBoolFlag(arg, kBriefFlag, >EST_FLAG(brief)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8009 |
ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8010 |
ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8011 |
ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8012 |
ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8013 |
ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8014 |
ParseInt32Flag(arg, kStackTraceDepthFlag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8015 |
>EST_FLAG(stack_trace_depth)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8016 |
ParseStringFlag(arg, kStreamResultToFlag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8017 |
>EST_FLAG(stream_result_to)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8018 |
ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8019 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8020 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8021 |
#if GTEST_USE_OWN_FLAGFILE_FLAG_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8022 |
static void LoadFlagsFromFile(const std::string& path) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8023 |
FILE* flagfile = posix::FOpen(path.c_str(), "r"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8024 |
if (!flagfile) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8025 |
GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8026 |
<< "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8027 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8028 |
std::string contents(ReadEntireFile(flagfile)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8029 |
posix::FClose(flagfile); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8030 |
std::vector<std::string> lines; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8031 |
SplitString(contents, '\n', &lines); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8032 |
for (size_t i = 0; i < lines.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8033 |
if (lines[i].empty()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8034 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8035 |
if (!ParseGoogleTestFlag(lines[i].c_str())) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8036 |
g_help_flag = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8037 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8038 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8039 |
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8040 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8041 |
// Parses the command line for Google Test flags, without initializing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8042 |
// other parts of Google Test. The type parameter CharType can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8043 |
// instantiated to either char or wchar_t. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8044 |
template <typename CharType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8045 |
void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8046 |
for (int i = 1; i < *argc; i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8047 |
const std::string arg_string = StreamableToString(argv[i]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8048 |
const char* const arg = arg_string.c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8049 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8050 |
using internal::ParseBoolFlag; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8051 |
using internal::ParseInt32Flag; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8052 |
using internal::ParseStringFlag; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8053 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8054 |
bool remove_flag = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8055 |
if (ParseGoogleTestFlag(arg)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8056 |
remove_flag = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8057 |
#if GTEST_USE_OWN_FLAGFILE_FLAG_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8058 |
} else if (ParseStringFlag(arg, kFlagfileFlag, >EST_FLAG(flagfile))) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8059 |
LoadFlagsFromFile(GTEST_FLAG(flagfile)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8060 |
remove_flag = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8061 |
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8062 |
} else if (arg_string == "--help" || arg_string == "-h" || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8063 |
arg_string == "-?" || arg_string == "/?" || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8064 |
HasGoogleTestFlagPrefix(arg)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8065 |
// Both help flag and unrecognized Google Test flags (excluding |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8066 |
// internal ones) trigger help display. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8067 |
g_help_flag = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8068 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8069 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8070 |
if (remove_flag) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8071 |
// Shift the remainder of the argv list left by one. Note |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8072 |
// that argv has (*argc + 1) elements, the last one always being |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8073 |
// NULL. The following loop moves the trailing NULL element as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8074 |
// well. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8075 |
for (int j = i; j != *argc; j++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8076 |
argv[j] = argv[j + 1]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8077 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8078 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8079 |
// Decrements the argument count. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8080 |
(*argc)--; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8081 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8082 |
// We also need to decrement the iterator as we just removed |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8083 |
// an element. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8084 |
i--; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8085 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8086 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8087 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8088 |
if (g_help_flag) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8089 |
// We print the help here instead of in RUN_ALL_TESTS(), as the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8090 |
// latter may not be called at all if the user is using Google |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8091 |
// Test with another testing framework. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8092 |
PrintColorEncoded(kColorEncodedHelpMessage); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8093 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8094 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8095 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8096 |
// Parses the command line for Google Test flags, without initializing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8097 |
// other parts of Google Test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8098 |
void ParseGoogleTestFlagsOnly(int* argc, char** argv) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8099 |
ParseGoogleTestFlagsOnlyImpl(argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8100 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8101 |
// Fix the value of *_NSGetArgc() on macOS, but if and only if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8102 |
// *_NSGetArgv() == argv |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8103 |
// Only applicable to char** version of argv |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8104 |
#if GTEST_OS_MAC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8105 |
#ifndef GTEST_OS_IOS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8106 |
if (*_NSGetArgv() == argv) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8107 |
*_NSGetArgc() = *argc; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8108 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8109 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8110 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8111 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8112 |
void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8113 |
ParseGoogleTestFlagsOnlyImpl(argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8114 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8115 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8116 |
// The internal implementation of InitGoogleTest(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8117 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8118 |
// The type parameter CharType can be instantiated to either char or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8119 |
// wchar_t. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8120 |
template <typename CharType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8121 |
void InitGoogleTestImpl(int* argc, CharType** argv) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8122 |
// We don't want to run the initialization code twice. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8123 |
if (GTestIsInitialized()) return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8124 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8125 |
if (*argc <= 0) return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8126 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8127 |
g_argvs.clear(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8128 |
for (int i = 0; i != *argc; i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8129 |
g_argvs.push_back(StreamableToString(argv[i])); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8130 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8131 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8132 |
#if GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8133 |
absl::InitializeSymbolizer(g_argvs[0].c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8134 |
#endif // GTEST_HAS_ABSL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8135 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8136 |
ParseGoogleTestFlagsOnly(argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8137 |
GetUnitTestImpl()->PostFlagParsingInit(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8138 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8139 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8140 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8141 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8142 |
// Initializes Google Test. This must be called before calling |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8143 |
// RUN_ALL_TESTS(). In particular, it parses a command line for the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8144 |
// flags that Google Test recognizes. Whenever a Google Test flag is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8145 |
// seen, it is removed from argv, and *argc is decremented. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8146 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8147 |
// No value is returned. Instead, the Google Test flag variables are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8148 |
// updated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8149 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8150 |
// Calling the function for the second time has no user-visible effect. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8151 |
void InitGoogleTest(int* argc, char** argv) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8152 |
#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8153 |
GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8154 |
#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8155 |
internal::InitGoogleTestImpl(argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8156 |
#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8157 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8158 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8159 |
// This overloaded version can be used in Windows programs compiled in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8160 |
// UNICODE mode. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8161 |
void InitGoogleTest(int* argc, wchar_t** argv) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8162 |
#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8163 |
GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8164 |
#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8165 |
internal::InitGoogleTestImpl(argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8166 |
#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8167 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8168 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8169 |
// This overloaded version can be used on Arduino/embedded platforms where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8170 |
// there is no argc/argv. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8171 |
void InitGoogleTest() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8172 |
// Since Arduino doesn't have a command line, fake out the argc/argv arguments |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8173 |
int argc = 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8174 |
const auto arg0 = "dummy"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8175 |
char* argv0 = const_cast<char*>(arg0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8176 |
char** argv = &argv0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8177 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8178 |
#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8179 |
GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(&argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8180 |
#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8181 |
internal::InitGoogleTestImpl(&argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8182 |
#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8183 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8184 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8185 |
std::string TempDir() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8186 |
#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8187 |
return GTEST_CUSTOM_TEMPDIR_FUNCTION_(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8188 |
#elif GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8189 |
return "\\temp\\"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8190 |
#elif GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8191 |
const char* temp_dir = internal::posix::GetEnv("TEMP"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8192 |
if (temp_dir == nullptr || temp_dir[0] == '\0') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8193 |
return "\\temp\\"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8194 |
} else if (temp_dir[strlen(temp_dir) - 1] == '\\') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8195 |
return temp_dir; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8196 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8197 |
return std::string(temp_dir) + "\\"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8198 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8199 |
#elif GTEST_OS_LINUX_ANDROID |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8200 |
const char* temp_dir = internal::posix::GetEnv("TEST_TMPDIR"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8201 |
if (temp_dir == nullptr || temp_dir[0] == '\0') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8202 |
return "/data/local/tmp/"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8203 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8204 |
return temp_dir; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8205 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8206 |
#elif GTEST_OS_LINUX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8207 |
const char* temp_dir = internal::posix::GetEnv("TEST_TMPDIR"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8208 |
if (temp_dir == nullptr || temp_dir[0] == '\0') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8209 |
return "/tmp/"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8210 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8211 |
return temp_dir; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8212 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8213 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8214 |
return "/tmp/"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8215 |
#endif // GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8216 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8217 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8218 |
// Class ScopedTrace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8219 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8220 |
// Pushes the given source file location and message onto a per-thread |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8221 |
// trace stack maintained by Google Test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8222 |
void ScopedTrace::PushTrace(const char* file, int line, std::string message) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8223 |
internal::TraceInfo trace; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8224 |
trace.file = file; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8225 |
trace.line = line; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8226 |
trace.message.swap(message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8227 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8228 |
UnitTest::GetInstance()->PushGTestTrace(trace); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8229 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8230 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8231 |
// Pops the info pushed by the c'tor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8232 |
ScopedTrace::~ScopedTrace() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8233 |
GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8234 |
UnitTest::GetInstance()->PopGTestTrace(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8235 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8236 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8237 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8238 |
// Copyright 2005, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8239 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8240 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8241 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8242 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8243 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8244 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8245 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8246 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8247 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8248 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8249 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8250 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8251 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8252 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8253 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8254 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8255 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8256 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8257 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8258 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8259 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8260 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8261 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8262 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8263 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8264 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8265 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8266 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8267 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8268 |
// This file implements death tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8269 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8270 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8271 |
#include <functional> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8272 |
#include <utility> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8273 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8274 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8275 |
#if GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8276 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8277 |
# if GTEST_OS_MAC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8278 |
# include <crt_externs.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8279 |
# endif // GTEST_OS_MAC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8280 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8281 |
# include <errno.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8282 |
# include <fcntl.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8283 |
# include <limits.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8284 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8285 |
# if GTEST_OS_LINUX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8286 |
# include <signal.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8287 |
# endif // GTEST_OS_LINUX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8288 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8289 |
# include <stdarg.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8290 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8291 |
# if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8292 |
# include <windows.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8293 |
# else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8294 |
# include <sys/mman.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8295 |
# include <sys/wait.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8296 |
# endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8297 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8298 |
# if GTEST_OS_QNX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8299 |
# include <spawn.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8300 |
# endif // GTEST_OS_QNX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8301 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8302 |
# if GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8303 |
# include <lib/fdio/fd.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8304 |
# include <lib/fdio/io.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8305 |
# include <lib/fdio/spawn.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8306 |
# include <lib/zx/channel.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8307 |
# include <lib/zx/port.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8308 |
# include <lib/zx/process.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8309 |
# include <lib/zx/socket.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8310 |
# include <zircon/processargs.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8311 |
# include <zircon/syscalls.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8312 |
# include <zircon/syscalls/policy.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8313 |
# include <zircon/syscalls/port.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8314 |
# endif // GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8315 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8316 |
#endif // GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8317 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8318 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8319 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8320 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8321 |
// Constants. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8322 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8323 |
// The default death test style. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8324 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8325 |
// This is defined in internal/gtest-port.h as "fast", but can be overridden by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8326 |
// a definition in internal/custom/gtest-port.h. The recommended value, which is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8327 |
// used internally at Google, is "threadsafe". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8328 |
static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8329 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8330 |
GTEST_DEFINE_string_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8331 |
death_test_style, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8332 |
internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8333 |
"Indicates how to run a death test in a forked child process: " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8334 |
"\"threadsafe\" (child process re-executes the test binary " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8335 |
"from the beginning, running only the specific death test) or " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8336 |
"\"fast\" (child process runs the death test immediately " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8337 |
"after forking)."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8338 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8339 |
GTEST_DEFINE_bool_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8340 |
death_test_use_fork, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8341 |
internal::BoolFromGTestEnv("death_test_use_fork", false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8342 |
"Instructs to use fork()/_exit() instead of clone() in death tests. " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8343 |
"Ignored and always uses fork() on POSIX systems where clone() is not " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8344 |
"implemented. Useful when running under valgrind or similar tools if " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8345 |
"those do not support clone(). Valgrind 3.3.1 will just fail if " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8346 |
"it sees an unsupported combination of clone() flags. " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8347 |
"It is not recommended to use this flag w/o valgrind though it will " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8348 |
"work in 99% of the cases. Once valgrind is fixed, this flag will " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8349 |
"most likely be removed."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8350 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8351 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8352 |
GTEST_DEFINE_string_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8353 |
internal_run_death_test, "", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8354 |
"Indicates the file, line number, temporal index of " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8355 |
"the single death test to run, and a file descriptor to " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8356 |
"which a success code may be sent, all separated by " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8357 |
"the '|' characters. This flag is specified if and only if the " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8358 |
"current process is a sub-process launched for running a thread-safe " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8359 |
"death test. FOR INTERNAL USE ONLY."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8360 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8361 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8362 |
#if GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8363 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8364 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8365 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8366 |
// Valid only for fast death tests. Indicates the code is running in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8367 |
// child process of a fast style death test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8368 |
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8369 |
static bool g_in_fast_death_test_child = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8370 |
# endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8371 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8372 |
// Returns a Boolean value indicating whether the caller is currently |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8373 |
// executing in the context of the death test child process. Tools such as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8374 |
// Valgrind heap checkers may need this to modify their behavior in death |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8375 |
// tests. IMPORTANT: This is an internal utility. Using it may break the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8376 |
// implementation of death tests. User code MUST NOT use it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8377 |
bool InDeathTestChild() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8378 |
# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8379 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8380 |
// On Windows and Fuchsia, death tests are thread-safe regardless of the value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8381 |
// of the death_test_style flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8382 |
return !GTEST_FLAG(internal_run_death_test).empty(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8383 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8384 |
# else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8385 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8386 |
if (GTEST_FLAG(death_test_style) == "threadsafe") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8387 |
return !GTEST_FLAG(internal_run_death_test).empty(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8388 |
else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8389 |
return g_in_fast_death_test_child; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8390 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8391 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8392 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8393 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8394 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8395 |
// ExitedWithCode constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8396 |
ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8397 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8398 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8399 |
// ExitedWithCode function-call operator. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8400 |
bool ExitedWithCode::operator()(int exit_status) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8401 |
# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8402 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8403 |
return exit_status == exit_code_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8404 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8405 |
# else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8406 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8407 |
return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8408 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8409 |
# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8410 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8411 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8412 |
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8413 |
// KilledBySignal constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8414 |
KilledBySignal::KilledBySignal(int signum) : signum_(signum) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8415 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8416 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8417 |
// KilledBySignal function-call operator. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8418 |
bool KilledBySignal::operator()(int exit_status) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8419 |
# if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8420 |
{ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8421 |
bool result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8422 |
if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8423 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8424 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8425 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8426 |
# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8427 |
return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8428 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8429 |
# endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8430 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8431 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8432 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8433 |
// Utilities needed for death tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8434 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8435 |
// Generates a textual description of a given exit code, in the format |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8436 |
// specified by wait(2). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8437 |
static std::string ExitSummary(int exit_code) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8438 |
Message m; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8439 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8440 |
# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8441 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8442 |
m << "Exited with exit status " << exit_code; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8443 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8444 |
# else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8445 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8446 |
if (WIFEXITED(exit_code)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8447 |
m << "Exited with exit status " << WEXITSTATUS(exit_code); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8448 |
} else if (WIFSIGNALED(exit_code)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8449 |
m << "Terminated by signal " << WTERMSIG(exit_code); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8450 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8451 |
# ifdef WCOREDUMP |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8452 |
if (WCOREDUMP(exit_code)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8453 |
m << " (core dumped)"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8454 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8455 |
# endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8456 |
# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8457 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8458 |
return m.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8459 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8460 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8461 |
// Returns true if exit_status describes a process that was terminated |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8462 |
// by a signal, or exited normally with a nonzero exit code. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8463 |
bool ExitedUnsuccessfully(int exit_status) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8464 |
return !ExitedWithCode(0)(exit_status); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8465 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8466 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8467 |
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8468 |
// Generates a textual failure message when a death test finds more than |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8469 |
// one thread running, or cannot determine the number of threads, prior |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8470 |
// to executing the given statement. It is the responsibility of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8471 |
// caller not to pass a thread_count of 1. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8472 |
static std::string DeathTestThreadWarning(size_t thread_count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8473 |
Message msg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8474 |
msg << "Death tests use fork(), which is unsafe particularly" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8475 |
<< " in a threaded context. For this test, " << GTEST_NAME_ << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8476 |
if (thread_count == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8477 |
msg << "couldn't detect the number of threads."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8478 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8479 |
msg << "detected " << thread_count << " threads."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8480 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8481 |
msg << " See " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8482 |
"https://github.com/google/googletest/blob/master/docs/" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8483 |
"advanced.md#death-tests-and-threads" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8484 |
<< " for more explanation and suggested solutions, especially if" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8485 |
<< " this is the last message you see before your test times out."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8486 |
return msg.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8487 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8488 |
# endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8489 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8490 |
// Flag characters for reporting a death test that did not die. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8491 |
static const char kDeathTestLived = 'L'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8492 |
static const char kDeathTestReturned = 'R'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8493 |
static const char kDeathTestThrew = 'T'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8494 |
static const char kDeathTestInternalError = 'I'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8495 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8496 |
#if GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8497 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8498 |
// File descriptor used for the pipe in the child process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8499 |
static const int kFuchsiaReadPipeFd = 3; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8500 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8501 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8502 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8503 |
// An enumeration describing all of the possible ways that a death test can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8504 |
// conclude. DIED means that the process died while executing the test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8505 |
// code; LIVED means that process lived beyond the end of the test code; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8506 |
// RETURNED means that the test statement attempted to execute a return |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8507 |
// statement, which is not allowed; THREW means that the test statement |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8508 |
// returned control by throwing an exception. IN_PROGRESS means the test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8509 |
// has not yet concluded. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8510 |
enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8511 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8512 |
// Routine for aborting the program which is safe to call from an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8513 |
// exec-style death test child process, in which case the error |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8514 |
// message is propagated back to the parent process. Otherwise, the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8515 |
// message is simply printed to stderr. In either case, the program |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8516 |
// then exits with status 1. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8517 |
static void DeathTestAbort(const std::string& message) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8518 |
// On a POSIX system, this function may be called from a threadsafe-style |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8519 |
// death test child process, which operates on a very small stack. Use |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8520 |
// the heap for any additional non-minuscule memory requirements. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8521 |
const InternalRunDeathTestFlag* const flag = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8522 |
GetUnitTestImpl()->internal_run_death_test_flag(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8523 |
if (flag != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8524 |
FILE* parent = posix::FDOpen(flag->write_fd(), "w"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8525 |
fputc(kDeathTestInternalError, parent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8526 |
fprintf(parent, "%s", message.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8527 |
fflush(parent); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8528 |
_exit(1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8529 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8530 |
fprintf(stderr, "%s", message.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8531 |
fflush(stderr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8532 |
posix::Abort(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8533 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8534 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8535 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8536 |
// A replacement for CHECK that calls DeathTestAbort if the assertion |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8537 |
// fails. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8538 |
# define GTEST_DEATH_TEST_CHECK_(expression) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8539 |
do { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8540 |
if (!::testing::internal::IsTrue(expression)) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8541 |
DeathTestAbort( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8542 |
::std::string("CHECK failed: File ") + __FILE__ + ", line " \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8543 |
+ ::testing::internal::StreamableToString(__LINE__) + ": " \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8544 |
+ #expression); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8545 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8546 |
} while (::testing::internal::AlwaysFalse()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8547 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8548 |
// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8549 |
// evaluating any system call that fulfills two conditions: it must return |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8550 |
// -1 on failure, and set errno to EINTR when it is interrupted and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8551 |
// should be tried again. The macro expands to a loop that repeatedly |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8552 |
// evaluates the expression as long as it evaluates to -1 and sets |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8553 |
// errno to EINTR. If the expression evaluates to -1 but errno is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8554 |
// something other than EINTR, DeathTestAbort is called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8555 |
# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8556 |
do { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8557 |
int gtest_retval; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8558 |
do { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8559 |
gtest_retval = (expression); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8560 |
} while (gtest_retval == -1 && errno == EINTR); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8561 |
if (gtest_retval == -1) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8562 |
DeathTestAbort( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8563 |
::std::string("CHECK failed: File ") + __FILE__ + ", line " \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8564 |
+ ::testing::internal::StreamableToString(__LINE__) + ": " \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8565 |
+ #expression + " != -1"); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8566 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8567 |
} while (::testing::internal::AlwaysFalse()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8568 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8569 |
// Returns the message describing the last system error in errno. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8570 |
std::string GetLastErrnoDescription() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8571 |
return errno == 0 ? "" : posix::StrError(errno); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8572 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8573 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8574 |
// This is called from a death test parent process to read a failure |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8575 |
// message from the death test child process and log it with the FATAL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8576 |
// severity. On Windows, the message is read from a pipe handle. On other |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8577 |
// platforms, it is read from a file descriptor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8578 |
static void FailFromInternalError(int fd) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8579 |
Message error; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8580 |
char buffer[256]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8581 |
int num_read; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8582 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8583 |
do { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8584 |
while ((num_read = posix::Read(fd, buffer, 255)) > 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8585 |
buffer[num_read] = '\0'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8586 |
error << buffer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8587 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8588 |
} while (num_read == -1 && errno == EINTR); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8589 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8590 |
if (num_read == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8591 |
GTEST_LOG_(FATAL) << error.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8592 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8593 |
const int last_error = errno; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8594 |
GTEST_LOG_(FATAL) << "Error while reading death test internal: " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8595 |
<< GetLastErrnoDescription() << " [" << last_error << "]"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8596 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8597 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8598 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8599 |
// Death test constructor. Increments the running death test count |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8600 |
// for the current test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8601 |
DeathTest::DeathTest() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8602 |
TestInfo* const info = GetUnitTestImpl()->current_test_info(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8603 |
if (info == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8604 |
DeathTestAbort("Cannot run a death test outside of a TEST or " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8605 |
"TEST_F construct"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8606 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8607 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8608 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8609 |
// Creates and returns a death test by dispatching to the current |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8610 |
// death test factory. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8611 |
bool DeathTest::Create(const char* statement, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8612 |
Matcher<const std::string&> matcher, const char* file, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8613 |
int line, DeathTest** test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8614 |
return GetUnitTestImpl()->death_test_factory()->Create( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8615 |
statement, std::move(matcher), file, line, test); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8616 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8617 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8618 |
const char* DeathTest::LastMessage() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8619 |
return last_death_test_message_.c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8620 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8621 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8622 |
void DeathTest::set_last_death_test_message(const std::string& message) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8623 |
last_death_test_message_ = message; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8624 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8625 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8626 |
std::string DeathTest::last_death_test_message_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8627 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8628 |
// Provides cross platform implementation for some death functionality. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8629 |
class DeathTestImpl : public DeathTest { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8630 |
protected: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8631 |
DeathTestImpl(const char* a_statement, Matcher<const std::string&> matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8632 |
: statement_(a_statement), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8633 |
matcher_(std::move(matcher)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8634 |
spawned_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8635 |
status_(-1), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8636 |
outcome_(IN_PROGRESS), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8637 |
read_fd_(-1), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8638 |
write_fd_(-1) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8639 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8640 |
// read_fd_ is expected to be closed and cleared by a derived class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8641 |
~DeathTestImpl() override { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8642 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8643 |
void Abort(AbortReason reason) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8644 |
bool Passed(bool status_ok) override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8645 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8646 |
const char* statement() const { return statement_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8647 |
bool spawned() const { return spawned_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8648 |
void set_spawned(bool is_spawned) { spawned_ = is_spawned; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8649 |
int status() const { return status_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8650 |
void set_status(int a_status) { status_ = a_status; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8651 |
DeathTestOutcome outcome() const { return outcome_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8652 |
void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8653 |
int read_fd() const { return read_fd_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8654 |
void set_read_fd(int fd) { read_fd_ = fd; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8655 |
int write_fd() const { return write_fd_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8656 |
void set_write_fd(int fd) { write_fd_ = fd; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8657 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8658 |
// Called in the parent process only. Reads the result code of the death |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8659 |
// test child process via a pipe, interprets it to set the outcome_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8660 |
// member, and closes read_fd_. Outputs diagnostics and terminates in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8661 |
// case of unexpected codes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8662 |
void ReadAndInterpretStatusByte(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8663 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8664 |
// Returns stderr output from the child process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8665 |
virtual std::string GetErrorLogs(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8666 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8667 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8668 |
// The textual content of the code this object is testing. This class |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8669 |
// doesn't own this string and should not attempt to delete it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8670 |
const char* const statement_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8671 |
// A matcher that's expected to match the stderr output by the child process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8672 |
Matcher<const std::string&> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8673 |
// True if the death test child process has been successfully spawned. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8674 |
bool spawned_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8675 |
// The exit status of the child process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8676 |
int status_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8677 |
// How the death test concluded. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8678 |
DeathTestOutcome outcome_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8679 |
// Descriptor to the read end of the pipe to the child process. It is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8680 |
// always -1 in the child process. The child keeps its write end of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8681 |
// pipe in write_fd_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8682 |
int read_fd_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8683 |
// Descriptor to the child's write end of the pipe to the parent process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8684 |
// It is always -1 in the parent process. The parent keeps its end of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8685 |
// pipe in read_fd_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8686 |
int write_fd_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8687 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8688 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8689 |
// Called in the parent process only. Reads the result code of the death |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8690 |
// test child process via a pipe, interprets it to set the outcome_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8691 |
// member, and closes read_fd_. Outputs diagnostics and terminates in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8692 |
// case of unexpected codes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8693 |
void DeathTestImpl::ReadAndInterpretStatusByte() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8694 |
char flag; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8695 |
int bytes_read; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8696 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8697 |
// The read() here blocks until data is available (signifying the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8698 |
// failure of the death test) or until the pipe is closed (signifying |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8699 |
// its success), so it's okay to call this in the parent before |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8700 |
// the child process has exited. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8701 |
do { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8702 |
bytes_read = posix::Read(read_fd(), &flag, 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8703 |
} while (bytes_read == -1 && errno == EINTR); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8704 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8705 |
if (bytes_read == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8706 |
set_outcome(DIED); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8707 |
} else if (bytes_read == 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8708 |
switch (flag) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8709 |
case kDeathTestReturned: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8710 |
set_outcome(RETURNED); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8711 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8712 |
case kDeathTestThrew: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8713 |
set_outcome(THREW); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8714 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8715 |
case kDeathTestLived: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8716 |
set_outcome(LIVED); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8717 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8718 |
case kDeathTestInternalError: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8719 |
FailFromInternalError(read_fd()); // Does not return. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8720 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8721 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8722 |
GTEST_LOG_(FATAL) << "Death test child process reported " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8723 |
<< "unexpected status byte (" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8724 |
<< static_cast<unsigned int>(flag) << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8725 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8726 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8727 |
GTEST_LOG_(FATAL) << "Read from death test child process failed: " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8728 |
<< GetLastErrnoDescription(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8729 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8730 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8731 |
set_read_fd(-1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8732 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8733 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8734 |
std::string DeathTestImpl::GetErrorLogs() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8735 |
return GetCapturedStderr(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8736 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8737 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8738 |
// Signals that the death test code which should have exited, didn't. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8739 |
// Should be called only in a death test child process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8740 |
// Writes a status byte to the child's status file descriptor, then |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8741 |
// calls _exit(1). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8742 |
void DeathTestImpl::Abort(AbortReason reason) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8743 |
// The parent process considers the death test to be a failure if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8744 |
// it finds any data in our pipe. So, here we write a single flag byte |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8745 |
// to the pipe, then exit. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8746 |
const char status_ch = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8747 |
reason == TEST_DID_NOT_DIE ? kDeathTestLived : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8748 |
reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8749 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8750 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8751 |
// We are leaking the descriptor here because on some platforms (i.e., |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8752 |
// when built as Windows DLL), destructors of global objects will still |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8753 |
// run after calling _exit(). On such systems, write_fd_ will be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8754 |
// indirectly closed from the destructor of UnitTestImpl, causing double |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8755 |
// close if it is also closed here. On debug configurations, double close |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8756 |
// may assert. As there are no in-process buffers to flush here, we are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8757 |
// relying on the OS to close the descriptor after the process terminates |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8758 |
// when the destructors are not run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8759 |
_exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8760 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8761 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8762 |
// Returns an indented copy of stderr output for a death test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8763 |
// This makes distinguishing death test output lines from regular log lines |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8764 |
// much easier. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8765 |
static ::std::string FormatDeathTestOutput(const ::std::string& output) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8766 |
::std::string ret; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8767 |
for (size_t at = 0; ; ) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8768 |
const size_t line_end = output.find('\n', at); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8769 |
ret += "[ DEATH ] "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8770 |
if (line_end == ::std::string::npos) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8771 |
ret += output.substr(at); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8772 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8773 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8774 |
ret += output.substr(at, line_end + 1 - at); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8775 |
at = line_end + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8776 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8777 |
return ret; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8778 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8779 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8780 |
// Assesses the success or failure of a death test, using both private |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8781 |
// members which have previously been set, and one argument: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8782 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8783 |
// Private data members: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8784 |
// outcome: An enumeration describing how the death test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8785 |
// concluded: DIED, LIVED, THREW, or RETURNED. The death test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8786 |
// fails in the latter three cases. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8787 |
// status: The exit status of the child process. On *nix, it is in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8788 |
// in the format specified by wait(2). On Windows, this is the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8789 |
// value supplied to the ExitProcess() API or a numeric code |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8790 |
// of the exception that terminated the program. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8791 |
// matcher_: A matcher that's expected to match the stderr output by the child |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8792 |
// process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8793 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8794 |
// Argument: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8795 |
// status_ok: true if exit_status is acceptable in the context of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8796 |
// this particular death test, which fails if it is false |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8797 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8798 |
// Returns true if and only if all of the above conditions are met. Otherwise, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8799 |
// the first failing condition, in the order given above, is the one that is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8800 |
// reported. Also sets the last death test message string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8801 |
bool DeathTestImpl::Passed(bool status_ok) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8802 |
if (!spawned()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8803 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8804 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8805 |
const std::string error_message = GetErrorLogs(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8806 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8807 |
bool success = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8808 |
Message buffer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8809 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8810 |
buffer << "Death test: " << statement() << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8811 |
switch (outcome()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8812 |
case LIVED: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8813 |
buffer << " Result: failed to die.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8814 |
<< " Error msg:\n" << FormatDeathTestOutput(error_message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8815 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8816 |
case THREW: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8817 |
buffer << " Result: threw an exception.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8818 |
<< " Error msg:\n" << FormatDeathTestOutput(error_message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8819 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8820 |
case RETURNED: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8821 |
buffer << " Result: illegal return in test statement.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8822 |
<< " Error msg:\n" << FormatDeathTestOutput(error_message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8823 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8824 |
case DIED: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8825 |
if (status_ok) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8826 |
if (matcher_.Matches(error_message)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8827 |
success = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8828 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8829 |
std::ostringstream stream; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8830 |
matcher_.DescribeTo(&stream); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8831 |
buffer << " Result: died but not with expected error.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8832 |
<< " Expected: " << stream.str() << "\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8833 |
<< "Actual msg:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8834 |
<< FormatDeathTestOutput(error_message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8835 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8836 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8837 |
buffer << " Result: died but not with expected exit code:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8838 |
<< " " << ExitSummary(status()) << "\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8839 |
<< "Actual msg:\n" << FormatDeathTestOutput(error_message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8840 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8841 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8842 |
case IN_PROGRESS: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8843 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8844 |
GTEST_LOG_(FATAL) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8845 |
<< "DeathTest::Passed somehow called before conclusion of test"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8846 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8847 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8848 |
DeathTest::set_last_death_test_message(buffer.GetString()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8849 |
return success; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8850 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8851 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8852 |
# if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8853 |
// WindowsDeathTest implements death tests on Windows. Due to the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8854 |
// specifics of starting new processes on Windows, death tests there are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8855 |
// always threadsafe, and Google Test considers the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8856 |
// --gtest_death_test_style=fast setting to be equivalent to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8857 |
// --gtest_death_test_style=threadsafe there. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8858 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8859 |
// A few implementation notes: Like the Linux version, the Windows |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8860 |
// implementation uses pipes for child-to-parent communication. But due to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8861 |
// the specifics of pipes on Windows, some extra steps are required: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8862 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8863 |
// 1. The parent creates a communication pipe and stores handles to both |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8864 |
// ends of it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8865 |
// 2. The parent starts the child and provides it with the information |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8866 |
// necessary to acquire the handle to the write end of the pipe. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8867 |
// 3. The child acquires the write end of the pipe and signals the parent |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8868 |
// using a Windows event. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8869 |
// 4. Now the parent can release the write end of the pipe on its side. If |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8870 |
// this is done before step 3, the object's reference count goes down to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8871 |
// 0 and it is destroyed, preventing the child from acquiring it. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8872 |
// parent now has to release it, or read operations on the read end of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8873 |
// the pipe will not return when the child terminates. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8874 |
// 5. The parent reads child's output through the pipe (outcome code and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8875 |
// any possible error messages) from the pipe, and its stderr and then |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8876 |
// determines whether to fail the test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8877 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8878 |
// Note: to distinguish Win32 API calls from the local method and function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8879 |
// calls, the former are explicitly resolved in the global namespace. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8880 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8881 |
class WindowsDeathTest : public DeathTestImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8882 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8883 |
WindowsDeathTest(const char* a_statement, Matcher<const std::string&> matcher, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8884 |
const char* file, int line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8885 |
: DeathTestImpl(a_statement, std::move(matcher)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8886 |
file_(file), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8887 |
line_(line) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8888 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8889 |
// All of these virtual functions are inherited from DeathTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8890 |
virtual int Wait(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8891 |
virtual TestRole AssumeRole(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8892 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8893 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8894 |
// The name of the file in which the death test is located. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8895 |
const char* const file_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8896 |
// The line number on which the death test is located. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8897 |
const int line_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8898 |
// Handle to the write end of the pipe to the child process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8899 |
AutoHandle write_handle_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8900 |
// Child process handle. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8901 |
AutoHandle child_handle_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8902 |
// Event the child process uses to signal the parent that it has |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8903 |
// acquired the handle to the write end of the pipe. After seeing this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8904 |
// event the parent can release its own handles to make sure its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8905 |
// ReadFile() calls return when the child terminates. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8906 |
AutoHandle event_handle_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8907 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8908 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8909 |
// Waits for the child in a death test to exit, returning its exit |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8910 |
// status, or 0 if no child process exists. As a side effect, sets the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8911 |
// outcome data member. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8912 |
int WindowsDeathTest::Wait() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8913 |
if (!spawned()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8914 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8915 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8916 |
// Wait until the child either signals that it has acquired the write end |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8917 |
// of the pipe or it dies. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8918 |
const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8919 |
switch (::WaitForMultipleObjects(2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8920 |
wait_handles, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8921 |
FALSE, // Waits for any of the handles. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8922 |
INFINITE)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8923 |
case WAIT_OBJECT_0: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8924 |
case WAIT_OBJECT_0 + 1: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8925 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8926 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8927 |
GTEST_DEATH_TEST_CHECK_(false); // Should not get here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8928 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8929 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8930 |
// The child has acquired the write end of the pipe or exited. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8931 |
// We release the handle on our side and continue. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8932 |
write_handle_.Reset(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8933 |
event_handle_.Reset(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8934 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8935 |
ReadAndInterpretStatusByte(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8936 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8937 |
// Waits for the child process to exit if it haven't already. This |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8938 |
// returns immediately if the child has already exited, regardless of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8939 |
// whether previous calls to WaitForMultipleObjects synchronized on this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8940 |
// handle or not. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8941 |
GTEST_DEATH_TEST_CHECK_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8942 |
WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8943 |
INFINITE)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8944 |
DWORD status_code; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8945 |
GTEST_DEATH_TEST_CHECK_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8946 |
::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8947 |
child_handle_.Reset(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8948 |
set_status(static_cast<int>(status_code)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8949 |
return status(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8950 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8951 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8952 |
// The AssumeRole process for a Windows death test. It creates a child |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8953 |
// process with the same executable as the current process to run the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8954 |
// death test. The child process is given the --gtest_filter and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8955 |
// --gtest_internal_run_death_test flags such that it knows to run the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8956 |
// current death test only. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8957 |
DeathTest::TestRole WindowsDeathTest::AssumeRole() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8958 |
const UnitTestImpl* const impl = GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8959 |
const InternalRunDeathTestFlag* const flag = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8960 |
impl->internal_run_death_test_flag(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8961 |
const TestInfo* const info = impl->current_test_info(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8962 |
const int death_test_index = info->result()->death_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8963 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8964 |
if (flag != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8965 |
// ParseInternalRunDeathTestFlag() has performed all the necessary |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8966 |
// processing. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8967 |
set_write_fd(flag->write_fd()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8968 |
return EXECUTE_TEST; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8969 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8970 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8971 |
// WindowsDeathTest uses an anonymous pipe to communicate results of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8972 |
// a death test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8973 |
SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8974 |
nullptr, TRUE}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8975 |
HANDLE read_handle, write_handle; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8976 |
GTEST_DEATH_TEST_CHECK_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8977 |
::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8978 |
0) // Default buffer size. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8979 |
!= FALSE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8980 |
set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8981 |
O_RDONLY)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8982 |
write_handle_.Reset(write_handle); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8983 |
event_handle_.Reset(::CreateEvent( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8984 |
&handles_are_inheritable, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8985 |
TRUE, // The event will automatically reset to non-signaled state. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8986 |
FALSE, // The initial state is non-signalled. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8987 |
nullptr)); // The even is unnamed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8988 |
GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8989 |
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8990 |
kFilterFlag + "=" + info->test_suite_name() + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8991 |
"." + info->name(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8992 |
const std::string internal_flag = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8993 |
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8994 |
"=" + file_ + "|" + StreamableToString(line_) + "|" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8995 |
StreamableToString(death_test_index) + "|" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8996 |
StreamableToString(static_cast<unsigned int>(::GetCurrentProcessId())) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8997 |
// size_t has the same width as pointers on both 32-bit and 64-bit |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8998 |
// Windows platforms. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8999 |
// See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9000 |
"|" + StreamableToString(reinterpret_cast<size_t>(write_handle)) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9001 |
"|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9002 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9003 |
char executable_path[_MAX_PATH + 1]; // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9004 |
GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9005 |
executable_path, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9006 |
_MAX_PATH)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9007 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9008 |
std::string command_line = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9009 |
std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9010 |
internal_flag + "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9011 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9012 |
DeathTest::set_last_death_test_message(""); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9013 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9014 |
CaptureStderr(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9015 |
// Flush the log buffers since the log streams are shared with the child. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9016 |
FlushInfoLog(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9017 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9018 |
// The child process will share the standard handles with the parent. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9019 |
STARTUPINFOA startup_info; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9020 |
memset(&startup_info, 0, sizeof(STARTUPINFO)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9021 |
startup_info.dwFlags = STARTF_USESTDHANDLES; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9022 |
startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9023 |
startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9024 |
startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9025 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9026 |
PROCESS_INFORMATION process_info; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9027 |
GTEST_DEATH_TEST_CHECK_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9028 |
::CreateProcessA( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9029 |
executable_path, const_cast<char*>(command_line.c_str()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9030 |
nullptr, // Retuned process handle is not inheritable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9031 |
nullptr, // Retuned thread handle is not inheritable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9032 |
TRUE, // Child inherits all inheritable handles (for write_handle_). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9033 |
0x0, // Default creation flags. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9034 |
nullptr, // Inherit the parent's environment. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9035 |
UnitTest::GetInstance()->original_working_dir(), &startup_info, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9036 |
&process_info) != FALSE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9037 |
child_handle_.Reset(process_info.hProcess); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9038 |
::CloseHandle(process_info.hThread); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9039 |
set_spawned(true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9040 |
return OVERSEE_TEST; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9041 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9042 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9043 |
# elif GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9044 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9045 |
class FuchsiaDeathTest : public DeathTestImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9046 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9047 |
FuchsiaDeathTest(const char* a_statement, Matcher<const std::string&> matcher, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9048 |
const char* file, int line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9049 |
: DeathTestImpl(a_statement, std::move(matcher)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9050 |
file_(file), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9051 |
line_(line) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9052 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9053 |
// All of these virtual functions are inherited from DeathTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9054 |
int Wait() override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9055 |
TestRole AssumeRole() override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9056 |
std::string GetErrorLogs() override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9057 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9058 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9059 |
// The name of the file in which the death test is located. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9060 |
const char* const file_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9061 |
// The line number on which the death test is located. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9062 |
const int line_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9063 |
// The stderr data captured by the child process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9064 |
std::string captured_stderr_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9065 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9066 |
zx::process child_process_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9067 |
zx::channel exception_channel_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9068 |
zx::socket stderr_socket_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9069 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9070 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9071 |
// Utility class for accumulating command-line arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9072 |
class Arguments { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9073 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9074 |
Arguments() { args_.push_back(nullptr); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9075 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9076 |
~Arguments() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9077 |
for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9078 |
++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9079 |
free(*i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9080 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9081 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9082 |
void AddArgument(const char* argument) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9083 |
args_.insert(args_.end() - 1, posix::StrDup(argument)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9084 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9085 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9086 |
template <typename Str> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9087 |
void AddArguments(const ::std::vector<Str>& arguments) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9088 |
for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9089 |
i != arguments.end(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9090 |
++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9091 |
args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9092 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9093 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9094 |
char* const* Argv() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9095 |
return &args_[0]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9096 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9097 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9098 |
int size() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9099 |
return static_cast<int>(args_.size()) - 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9100 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9101 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9102 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9103 |
std::vector<char*> args_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9104 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9105 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9106 |
// Waits for the child in a death test to exit, returning its exit |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9107 |
// status, or 0 if no child process exists. As a side effect, sets the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9108 |
// outcome data member. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9109 |
int FuchsiaDeathTest::Wait() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9110 |
const int kProcessKey = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9111 |
const int kSocketKey = 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9112 |
const int kExceptionKey = 2; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9113 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9114 |
if (!spawned()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9115 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9116 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9117 |
// Create a port to wait for socket/task/exception events. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9118 |
zx_status_t status_zx; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9119 |
zx::port port; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9120 |
status_zx = zx::port::create(0, &port); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9121 |
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9122 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9123 |
// Register to wait for the child process to terminate. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9124 |
status_zx = child_process_.wait_async( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9125 |
port, kProcessKey, ZX_PROCESS_TERMINATED, 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9126 |
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9127 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9128 |
// Register to wait for the socket to be readable or closed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9129 |
status_zx = stderr_socket_.wait_async( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9130 |
port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9131 |
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9132 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9133 |
// Register to wait for an exception. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9134 |
status_zx = exception_channel_.wait_async( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9135 |
port, kExceptionKey, ZX_CHANNEL_READABLE, 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9136 |
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9137 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9138 |
bool process_terminated = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9139 |
bool socket_closed = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9140 |
do { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9141 |
zx_port_packet_t packet = {}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9142 |
status_zx = port.wait(zx::time::infinite(), &packet); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9143 |
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9144 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9145 |
if (packet.key == kExceptionKey) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9146 |
// Process encountered an exception. Kill it directly rather than |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9147 |
// letting other handlers process the event. We will get a kProcessKey |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9148 |
// event when the process actually terminates. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9149 |
status_zx = child_process_.kill(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9150 |
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9151 |
} else if (packet.key == kProcessKey) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9152 |
// Process terminated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9153 |
GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9154 |
GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_PROCESS_TERMINATED); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9155 |
process_terminated = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9156 |
} else if (packet.key == kSocketKey) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9157 |
GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9158 |
if (packet.signal.observed & ZX_SOCKET_READABLE) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9159 |
// Read data from the socket. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9160 |
constexpr size_t kBufferSize = 1024; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9161 |
do { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9162 |
size_t old_length = captured_stderr_.length(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9163 |
size_t bytes_read = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9164 |
captured_stderr_.resize(old_length + kBufferSize); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9165 |
status_zx = stderr_socket_.read( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9166 |
0, &captured_stderr_.front() + old_length, kBufferSize, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9167 |
&bytes_read); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9168 |
captured_stderr_.resize(old_length + bytes_read); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9169 |
} while (status_zx == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9170 |
if (status_zx == ZX_ERR_PEER_CLOSED) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9171 |
socket_closed = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9172 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9173 |
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_ERR_SHOULD_WAIT); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9174 |
status_zx = stderr_socket_.wait_async( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9175 |
port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9176 |
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9177 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9178 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9179 |
GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_SOCKET_PEER_CLOSED); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9180 |
socket_closed = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9181 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9182 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9183 |
} while (!process_terminated && !socket_closed); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9184 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9185 |
ReadAndInterpretStatusByte(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9186 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9187 |
zx_info_process_v2_t buffer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9188 |
status_zx = child_process_.get_info( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9189 |
ZX_INFO_PROCESS_V2, &buffer, sizeof(buffer), nullptr, nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9190 |
GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9191 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9192 |
GTEST_DEATH_TEST_CHECK_(buffer.flags & ZX_INFO_PROCESS_FLAG_EXITED); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9193 |
set_status(static_cast<int>(buffer.return_code)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9194 |
return status(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9195 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9196 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9197 |
// The AssumeRole process for a Fuchsia death test. It creates a child |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9198 |
// process with the same executable as the current process to run the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9199 |
// death test. The child process is given the --gtest_filter and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9200 |
// --gtest_internal_run_death_test flags such that it knows to run the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9201 |
// current death test only. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9202 |
DeathTest::TestRole FuchsiaDeathTest::AssumeRole() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9203 |
const UnitTestImpl* const impl = GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9204 |
const InternalRunDeathTestFlag* const flag = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9205 |
impl->internal_run_death_test_flag(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9206 |
const TestInfo* const info = impl->current_test_info(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9207 |
const int death_test_index = info->result()->death_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9208 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9209 |
if (flag != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9210 |
// ParseInternalRunDeathTestFlag() has performed all the necessary |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9211 |
// processing. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9212 |
set_write_fd(kFuchsiaReadPipeFd); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9213 |
return EXECUTE_TEST; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9214 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9215 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9216 |
// Flush the log buffers since the log streams are shared with the child. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9217 |
FlushInfoLog(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9218 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9219 |
// Build the child process command line. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9220 |
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9221 |
kFilterFlag + "=" + info->test_suite_name() + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9222 |
"." + info->name(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9223 |
const std::string internal_flag = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9224 |
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9225 |
+ file_ + "|" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9226 |
+ StreamableToString(line_) + "|" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9227 |
+ StreamableToString(death_test_index); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9228 |
Arguments args; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9229 |
args.AddArguments(GetInjectableArgvs()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9230 |
args.AddArgument(filter_flag.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9231 |
args.AddArgument(internal_flag.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9232 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9233 |
// Build the pipe for communication with the child. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9234 |
zx_status_t status; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9235 |
zx_handle_t child_pipe_handle; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9236 |
int child_pipe_fd; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9237 |
status = fdio_pipe_half(&child_pipe_fd, &child_pipe_handle); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9238 |
GTEST_DEATH_TEST_CHECK_(status == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9239 |
set_read_fd(child_pipe_fd); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9240 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9241 |
// Set the pipe handle for the child. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9242 |
fdio_spawn_action_t spawn_actions[2] = {}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9243 |
fdio_spawn_action_t* add_handle_action = &spawn_actions[0]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9244 |
add_handle_action->action = FDIO_SPAWN_ACTION_ADD_HANDLE; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9245 |
add_handle_action->h.id = PA_HND(PA_FD, kFuchsiaReadPipeFd); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9246 |
add_handle_action->h.handle = child_pipe_handle; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9247 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9248 |
// Create a socket pair will be used to receive the child process' stderr. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9249 |
zx::socket stderr_producer_socket; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9250 |
status = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9251 |
zx::socket::create(0, &stderr_producer_socket, &stderr_socket_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9252 |
GTEST_DEATH_TEST_CHECK_(status >= 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9253 |
int stderr_producer_fd = -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9254 |
status = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9255 |
fdio_fd_create(stderr_producer_socket.release(), &stderr_producer_fd); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9256 |
GTEST_DEATH_TEST_CHECK_(status >= 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9257 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9258 |
// Make the stderr socket nonblocking. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9259 |
GTEST_DEATH_TEST_CHECK_(fcntl(stderr_producer_fd, F_SETFL, 0) == 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9260 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9261 |
fdio_spawn_action_t* add_stderr_action = &spawn_actions[1]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9262 |
add_stderr_action->action = FDIO_SPAWN_ACTION_CLONE_FD; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9263 |
add_stderr_action->fd.local_fd = stderr_producer_fd; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9264 |
add_stderr_action->fd.target_fd = STDERR_FILENO; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9265 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9266 |
// Create a child job. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9267 |
zx_handle_t child_job = ZX_HANDLE_INVALID; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9268 |
status = zx_job_create(zx_job_default(), 0, & child_job); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9269 |
GTEST_DEATH_TEST_CHECK_(status == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9270 |
zx_policy_basic_t policy; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9271 |
policy.condition = ZX_POL_NEW_ANY; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9272 |
policy.policy = ZX_POL_ACTION_ALLOW; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9273 |
status = zx_job_set_policy( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9274 |
child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, &policy, 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9275 |
GTEST_DEATH_TEST_CHECK_(status == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9276 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9277 |
// Create an exception channel attached to the |child_job|, to allow |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9278 |
// us to suppress the system default exception handler from firing. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9279 |
status = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9280 |
zx_task_create_exception_channel( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9281 |
child_job, 0, exception_channel_.reset_and_get_address()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9282 |
GTEST_DEATH_TEST_CHECK_(status == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9283 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9284 |
// Spawn the child process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9285 |
status = fdio_spawn_etc( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9286 |
child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0], args.Argv(), nullptr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9287 |
2, spawn_actions, child_process_.reset_and_get_address(), nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9288 |
GTEST_DEATH_TEST_CHECK_(status == ZX_OK); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9289 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9290 |
set_spawned(true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9291 |
return OVERSEE_TEST; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9292 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9293 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9294 |
std::string FuchsiaDeathTest::GetErrorLogs() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9295 |
return captured_stderr_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9296 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9297 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9298 |
#else // We are neither on Windows, nor on Fuchsia. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9299 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9300 |
// ForkingDeathTest provides implementations for most of the abstract |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9301 |
// methods of the DeathTest interface. Only the AssumeRole method is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9302 |
// left undefined. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9303 |
class ForkingDeathTest : public DeathTestImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9304 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9305 |
ForkingDeathTest(const char* statement, Matcher<const std::string&> matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9306 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9307 |
// All of these virtual functions are inherited from DeathTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9308 |
int Wait() override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9309 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9310 |
protected: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9311 |
void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9312 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9313 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9314 |
// PID of child process during death test; 0 in the child process itself. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9315 |
pid_t child_pid_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9316 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9317 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9318 |
// Constructs a ForkingDeathTest. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9319 |
ForkingDeathTest::ForkingDeathTest(const char* a_statement, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9320 |
Matcher<const std::string&> matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9321 |
: DeathTestImpl(a_statement, std::move(matcher)), child_pid_(-1) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9322 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9323 |
// Waits for the child in a death test to exit, returning its exit |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9324 |
// status, or 0 if no child process exists. As a side effect, sets the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9325 |
// outcome data member. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9326 |
int ForkingDeathTest::Wait() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9327 |
if (!spawned()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9328 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9329 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9330 |
ReadAndInterpretStatusByte(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9331 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9332 |
int status_value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9333 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9334 |
set_status(status_value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9335 |
return status_value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9336 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9337 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9338 |
// A concrete death test class that forks, then immediately runs the test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9339 |
// in the child process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9340 |
class NoExecDeathTest : public ForkingDeathTest { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9341 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9342 |
NoExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9343 |
: ForkingDeathTest(a_statement, std::move(matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9344 |
TestRole AssumeRole() override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9345 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9346 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9347 |
// The AssumeRole process for a fork-and-run death test. It implements a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9348 |
// straightforward fork, with a simple pipe to transmit the status byte. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9349 |
DeathTest::TestRole NoExecDeathTest::AssumeRole() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9350 |
const size_t thread_count = GetThreadCount(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9351 |
if (thread_count != 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9352 |
GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9353 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9354 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9355 |
int pipe_fd[2]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9356 |
GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9357 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9358 |
DeathTest::set_last_death_test_message(""); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9359 |
CaptureStderr(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9360 |
// When we fork the process below, the log file buffers are copied, but the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9361 |
// file descriptors are shared. We flush all log files here so that closing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9362 |
// the file descriptors in the child process doesn't throw off the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9363 |
// synchronization between descriptors and buffers in the parent process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9364 |
// This is as close to the fork as possible to avoid a race condition in case |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9365 |
// there are multiple threads running before the death test, and another |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9366 |
// thread writes to the log file. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9367 |
FlushInfoLog(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9368 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9369 |
const pid_t child_pid = fork(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9370 |
GTEST_DEATH_TEST_CHECK_(child_pid != -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9371 |
set_child_pid(child_pid); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9372 |
if (child_pid == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9373 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9374 |
set_write_fd(pipe_fd[1]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9375 |
// Redirects all logging to stderr in the child process to prevent |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9376 |
// concurrent writes to the log files. We capture stderr in the parent |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9377 |
// process and append the child process' output to a log. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9378 |
LogToStderr(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9379 |
// Event forwarding to the listeners of event listener API mush be shut |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9380 |
// down in death test subprocesses. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9381 |
GetUnitTestImpl()->listeners()->SuppressEventForwarding(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9382 |
g_in_fast_death_test_child = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9383 |
return EXECUTE_TEST; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9384 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9385 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9386 |
set_read_fd(pipe_fd[0]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9387 |
set_spawned(true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9388 |
return OVERSEE_TEST; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9389 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9390 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9391 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9392 |
// A concrete death test class that forks and re-executes the main |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9393 |
// program from the beginning, with command-line flags set that cause |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9394 |
// only this specific death test to be run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9395 |
class ExecDeathTest : public ForkingDeathTest { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9396 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9397 |
ExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9398 |
const char* file, int line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9399 |
: ForkingDeathTest(a_statement, std::move(matcher)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9400 |
file_(file), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9401 |
line_(line) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9402 |
TestRole AssumeRole() override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9403 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9404 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9405 |
static ::std::vector<std::string> GetArgvsForDeathTestChildProcess() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9406 |
::std::vector<std::string> args = GetInjectableArgvs(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9407 |
# if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9408 |
::std::vector<std::string> extra_args = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9409 |
GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9410 |
args.insert(args.end(), extra_args.begin(), extra_args.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9411 |
# endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9412 |
return args; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9413 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9414 |
// The name of the file in which the death test is located. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9415 |
const char* const file_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9416 |
// The line number on which the death test is located. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9417 |
const int line_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9418 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9419 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9420 |
// Utility class for accumulating command-line arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9421 |
class Arguments { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9422 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9423 |
Arguments() { args_.push_back(nullptr); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9424 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9425 |
~Arguments() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9426 |
for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9427 |
++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9428 |
free(*i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9429 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9430 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9431 |
void AddArgument(const char* argument) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9432 |
args_.insert(args_.end() - 1, posix::StrDup(argument)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9433 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9434 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9435 |
template <typename Str> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9436 |
void AddArguments(const ::std::vector<Str>& arguments) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9437 |
for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9438 |
i != arguments.end(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9439 |
++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9440 |
args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9441 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9442 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9443 |
char* const* Argv() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9444 |
return &args_[0]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9445 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9446 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9447 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9448 |
std::vector<char*> args_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9449 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9450 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9451 |
// A struct that encompasses the arguments to the child process of a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9452 |
// threadsafe-style death test process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9453 |
struct ExecDeathTestArgs { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9454 |
char* const* argv; // Command-line arguments for the child's call to exec |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9455 |
int close_fd; // File descriptor to close; the read end of a pipe |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9456 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9457 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9458 |
# if GTEST_OS_QNX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9459 |
extern "C" char** environ; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9460 |
# else // GTEST_OS_QNX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9461 |
// The main function for a threadsafe-style death test child process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9462 |
// This function is called in a clone()-ed process and thus must avoid |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9463 |
// any potentially unsafe operations like malloc or libc functions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9464 |
static int ExecDeathTestChildMain(void* child_arg) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9465 |
ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9466 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9467 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9468 |
// We need to execute the test program in the same environment where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9469 |
// it was originally invoked. Therefore we change to the original |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9470 |
// working directory first. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9471 |
const char* const original_dir = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9472 |
UnitTest::GetInstance()->original_working_dir(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9473 |
// We can safely call chdir() as it's a direct system call. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9474 |
if (chdir(original_dir) != 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9475 |
DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9476 |
GetLastErrnoDescription()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9477 |
return EXIT_FAILURE; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9478 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9479 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9480 |
// We can safely call execv() as it's almost a direct system call. We |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9481 |
// cannot use execvp() as it's a libc function and thus potentially |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9482 |
// unsafe. Since execv() doesn't search the PATH, the user must |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9483 |
// invoke the test program via a valid path that contains at least |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9484 |
// one path separator. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9485 |
execv(args->argv[0], args->argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9486 |
DeathTestAbort(std::string("execv(") + args->argv[0] + ", ...) in " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9487 |
original_dir + " failed: " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9488 |
GetLastErrnoDescription()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9489 |
return EXIT_FAILURE; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9490 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9491 |
# endif // GTEST_OS_QNX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9492 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9493 |
# if GTEST_HAS_CLONE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9494 |
// Two utility routines that together determine the direction the stack |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9495 |
// grows. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9496 |
// This could be accomplished more elegantly by a single recursive |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9497 |
// function, but we want to guard against the unlikely possibility of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9498 |
// a smart compiler optimizing the recursion away. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9499 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9500 |
// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9501 |
// StackLowerThanAddress into StackGrowsDown, which then doesn't give |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9502 |
// correct answer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9503 |
static void StackLowerThanAddress(const void* ptr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9504 |
bool* result) GTEST_NO_INLINE_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9505 |
// Make sure sanitizers do not tamper with the stack here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9506 |
// Ideally, we want to use `__builtin_frame_address` instead of a local variable |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9507 |
// address with sanitizer disabled, but it does not work when the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9508 |
// compiler optimizes the stack frame out, which happens on PowerPC targets. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9509 |
// HWAddressSanitizer add a random tag to the MSB of the local variable address, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9510 |
// making comparison result unpredictable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9511 |
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9512 |
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9513 |
static void StackLowerThanAddress(const void* ptr, bool* result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9514 |
int dummy = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9515 |
*result = std::less<const void*>()(&dummy, ptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9516 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9517 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9518 |
// Make sure AddressSanitizer does not tamper with the stack here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9519 |
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9520 |
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9521 |
static bool StackGrowsDown() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9522 |
int dummy = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9523 |
bool result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9524 |
StackLowerThanAddress(&dummy, &result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9525 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9526 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9527 |
# endif // GTEST_HAS_CLONE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9528 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9529 |
// Spawns a child process with the same executable as the current process in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9530 |
// a thread-safe manner and instructs it to run the death test. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9531 |
// implementation uses fork(2) + exec. On systems where clone(2) is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9532 |
// available, it is used instead, being slightly more thread-safe. On QNX, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9533 |
// fork supports only single-threaded environments, so this function uses |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9534 |
// spawn(2) there instead. The function dies with an error message if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9535 |
// anything goes wrong. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9536 |
static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9537 |
ExecDeathTestArgs args = { argv, close_fd }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9538 |
pid_t child_pid = -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9539 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9540 |
# if GTEST_OS_QNX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9541 |
// Obtains the current directory and sets it to be closed in the child |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9542 |
// process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9543 |
const int cwd_fd = open(".", O_RDONLY); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9544 |
GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9545 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9546 |
// We need to execute the test program in the same environment where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9547 |
// it was originally invoked. Therefore we change to the original |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9548 |
// working directory first. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9549 |
const char* const original_dir = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9550 |
UnitTest::GetInstance()->original_working_dir(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9551 |
// We can safely call chdir() as it's a direct system call. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9552 |
if (chdir(original_dir) != 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9553 |
DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9554 |
GetLastErrnoDescription()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9555 |
return EXIT_FAILURE; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9556 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9557 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9558 |
int fd_flags; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9559 |
// Set close_fd to be closed after spawn. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9560 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9561 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9562 |
fd_flags | FD_CLOEXEC)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9563 |
struct inheritance inherit = {0}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9564 |
// spawn is a system call. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9565 |
child_pid = spawn(args.argv[0], 0, nullptr, &inherit, args.argv, environ); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9566 |
// Restores the current working directory. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9567 |
GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9568 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9569 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9570 |
# else // GTEST_OS_QNX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9571 |
# if GTEST_OS_LINUX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9572 |
// When a SIGPROF signal is received while fork() or clone() are executing, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9573 |
// the process may hang. To avoid this, we ignore SIGPROF here and re-enable |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9574 |
// it after the call to fork()/clone() is complete. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9575 |
struct sigaction saved_sigprof_action; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9576 |
struct sigaction ignore_sigprof_action; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9577 |
memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9578 |
sigemptyset(&ignore_sigprof_action.sa_mask); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9579 |
ignore_sigprof_action.sa_handler = SIG_IGN; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9580 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9581 |
SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9582 |
# endif // GTEST_OS_LINUX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9583 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9584 |
# if GTEST_HAS_CLONE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9585 |
const bool use_fork = GTEST_FLAG(death_test_use_fork); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9586 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9587 |
if (!use_fork) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9588 |
static const bool stack_grows_down = StackGrowsDown(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9589 |
const auto stack_size = static_cast<size_t>(getpagesize() * 2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9590 |
// MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9591 |
void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9592 |
MAP_ANON | MAP_PRIVATE, -1, 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9593 |
GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9594 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9595 |
// Maximum stack alignment in bytes: For a downward-growing stack, this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9596 |
// amount is subtracted from size of the stack space to get an address |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9597 |
// that is within the stack space and is aligned on all systems we care |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9598 |
// about. As far as I know there is no ABI with stack alignment greater |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9599 |
// than 64. We assume stack and stack_size already have alignment of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9600 |
// kMaxStackAlignment. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9601 |
const size_t kMaxStackAlignment = 64; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9602 |
void* const stack_top = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9603 |
static_cast<char*>(stack) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9604 |
(stack_grows_down ? stack_size - kMaxStackAlignment : 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9605 |
GTEST_DEATH_TEST_CHECK_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9606 |
static_cast<size_t>(stack_size) > kMaxStackAlignment && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9607 |
reinterpret_cast<uintptr_t>(stack_top) % kMaxStackAlignment == 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9608 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9609 |
child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9610 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9611 |
GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9612 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9613 |
# else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9614 |
const bool use_fork = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9615 |
# endif // GTEST_HAS_CLONE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9616 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9617 |
if (use_fork && (child_pid = fork()) == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9618 |
ExecDeathTestChildMain(&args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9619 |
_exit(0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9620 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9621 |
# endif // GTEST_OS_QNX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9622 |
# if GTEST_OS_LINUX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9623 |
GTEST_DEATH_TEST_CHECK_SYSCALL_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9624 |
sigaction(SIGPROF, &saved_sigprof_action, nullptr)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9625 |
# endif // GTEST_OS_LINUX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9626 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9627 |
GTEST_DEATH_TEST_CHECK_(child_pid != -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9628 |
return child_pid; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9629 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9630 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9631 |
// The AssumeRole process for a fork-and-exec death test. It re-executes the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9632 |
// main program from the beginning, setting the --gtest_filter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9633 |
// and --gtest_internal_run_death_test flags to cause only the current |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9634 |
// death test to be re-run. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9635 |
DeathTest::TestRole ExecDeathTest::AssumeRole() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9636 |
const UnitTestImpl* const impl = GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9637 |
const InternalRunDeathTestFlag* const flag = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9638 |
impl->internal_run_death_test_flag(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9639 |
const TestInfo* const info = impl->current_test_info(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9640 |
const int death_test_index = info->result()->death_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9641 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9642 |
if (flag != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9643 |
set_write_fd(flag->write_fd()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9644 |
return EXECUTE_TEST; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9645 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9646 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9647 |
int pipe_fd[2]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9648 |
GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9649 |
// Clear the close-on-exec flag on the write end of the pipe, lest |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9650 |
// it be closed when the child process does an exec: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9651 |
GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9652 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9653 |
const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9654 |
kFilterFlag + "=" + info->test_suite_name() + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9655 |
"." + info->name(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9656 |
const std::string internal_flag = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9657 |
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9658 |
+ file_ + "|" + StreamableToString(line_) + "|" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9659 |
+ StreamableToString(death_test_index) + "|" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9660 |
+ StreamableToString(pipe_fd[1]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9661 |
Arguments args; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9662 |
args.AddArguments(GetArgvsForDeathTestChildProcess()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9663 |
args.AddArgument(filter_flag.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9664 |
args.AddArgument(internal_flag.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9665 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9666 |
DeathTest::set_last_death_test_message(""); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9667 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9668 |
CaptureStderr(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9669 |
// See the comment in NoExecDeathTest::AssumeRole for why the next line |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9670 |
// is necessary. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9671 |
FlushInfoLog(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9672 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9673 |
const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9674 |
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9675 |
set_child_pid(child_pid); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9676 |
set_read_fd(pipe_fd[0]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9677 |
set_spawned(true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9678 |
return OVERSEE_TEST; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9679 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9680 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9681 |
# endif // !GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9682 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9683 |
// Creates a concrete DeathTest-derived class that depends on the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9684 |
// --gtest_death_test_style flag, and sets the pointer pointed to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9685 |
// by the "test" argument to its address. If the test should be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9686 |
// skipped, sets that pointer to NULL. Returns true, unless the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9687 |
// flag is set to an invalid value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9688 |
bool DefaultDeathTestFactory::Create(const char* statement, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9689 |
Matcher<const std::string&> matcher, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9690 |
const char* file, int line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9691 |
DeathTest** test) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9692 |
UnitTestImpl* const impl = GetUnitTestImpl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9693 |
const InternalRunDeathTestFlag* const flag = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9694 |
impl->internal_run_death_test_flag(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9695 |
const int death_test_index = impl->current_test_info() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9696 |
->increment_death_test_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9697 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9698 |
if (flag != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9699 |
if (death_test_index > flag->index()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9700 |
DeathTest::set_last_death_test_message( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9701 |
"Death test count (" + StreamableToString(death_test_index) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9702 |
+ ") somehow exceeded expected maximum (" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9703 |
+ StreamableToString(flag->index()) + ")"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9704 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9705 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9706 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9707 |
if (!(flag->file() == file && flag->line() == line && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9708 |
flag->index() == death_test_index)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9709 |
*test = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9710 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9711 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9712 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9713 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9714 |
# if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9715 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9716 |
if (GTEST_FLAG(death_test_style) == "threadsafe" || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9717 |
GTEST_FLAG(death_test_style) == "fast") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9718 |
*test = new WindowsDeathTest(statement, std::move(matcher), file, line); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9719 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9720 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9721 |
# elif GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9722 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9723 |
if (GTEST_FLAG(death_test_style) == "threadsafe" || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9724 |
GTEST_FLAG(death_test_style) == "fast") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9725 |
*test = new FuchsiaDeathTest(statement, std::move(matcher), file, line); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9726 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9727 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9728 |
# else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9729 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9730 |
if (GTEST_FLAG(death_test_style) == "threadsafe") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9731 |
*test = new ExecDeathTest(statement, std::move(matcher), file, line); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9732 |
} else if (GTEST_FLAG(death_test_style) == "fast") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9733 |
*test = new NoExecDeathTest(statement, std::move(matcher)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9734 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9735 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9736 |
# endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9737 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9738 |
else { // NOLINT - this is more readable than unbalanced brackets inside #if. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9739 |
DeathTest::set_last_death_test_message( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9740 |
"Unknown death test style \"" + GTEST_FLAG(death_test_style) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9741 |
+ "\" encountered"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9742 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9743 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9744 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9745 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9746 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9747 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9748 |
# if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9749 |
// Recreates the pipe and event handles from the provided parameters, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9750 |
// signals the event, and returns a file descriptor wrapped around the pipe |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9751 |
// handle. This function is called in the child process only. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9752 |
static int GetStatusFileDescriptor(unsigned int parent_process_id, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9753 |
size_t write_handle_as_size_t, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9754 |
size_t event_handle_as_size_t) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9755 |
AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9756 |
FALSE, // Non-inheritable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9757 |
parent_process_id)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9758 |
if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9759 |
DeathTestAbort("Unable to open parent process " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9760 |
StreamableToString(parent_process_id)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9761 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9762 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9763 |
GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9764 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9765 |
const HANDLE write_handle = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9766 |
reinterpret_cast<HANDLE>(write_handle_as_size_t); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9767 |
HANDLE dup_write_handle; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9768 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9769 |
// The newly initialized handle is accessible only in the parent |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9770 |
// process. To obtain one accessible within the child, we need to use |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9771 |
// DuplicateHandle. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9772 |
if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9773 |
::GetCurrentProcess(), &dup_write_handle, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9774 |
0x0, // Requested privileges ignored since |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9775 |
// DUPLICATE_SAME_ACCESS is used. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9776 |
FALSE, // Request non-inheritable handler. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9777 |
DUPLICATE_SAME_ACCESS)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9778 |
DeathTestAbort("Unable to duplicate the pipe handle " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9779 |
StreamableToString(write_handle_as_size_t) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9780 |
" from the parent process " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9781 |
StreamableToString(parent_process_id)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9782 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9783 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9784 |
const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9785 |
HANDLE dup_event_handle; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9786 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9787 |
if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9788 |
::GetCurrentProcess(), &dup_event_handle, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9789 |
0x0, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9790 |
FALSE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9791 |
DUPLICATE_SAME_ACCESS)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9792 |
DeathTestAbort("Unable to duplicate the event handle " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9793 |
StreamableToString(event_handle_as_size_t) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9794 |
" from the parent process " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9795 |
StreamableToString(parent_process_id)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9796 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9797 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9798 |
const int write_fd = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9799 |
::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9800 |
if (write_fd == -1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9801 |
DeathTestAbort("Unable to convert pipe handle " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9802 |
StreamableToString(write_handle_as_size_t) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9803 |
" to a file descriptor"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9804 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9805 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9806 |
// Signals the parent that the write end of the pipe has been acquired |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9807 |
// so the parent can release its own write end. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9808 |
::SetEvent(dup_event_handle); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9809 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9810 |
return write_fd; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9811 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9812 |
# endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9813 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9814 |
// Returns a newly created InternalRunDeathTestFlag object with fields |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9815 |
// initialized from the GTEST_FLAG(internal_run_death_test) flag if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9816 |
// the flag is specified; otherwise returns NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9817 |
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9818 |
if (GTEST_FLAG(internal_run_death_test) == "") return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9819 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9820 |
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9821 |
// can use it here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9822 |
int line = -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9823 |
int index = -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9824 |
::std::vector< ::std::string> fields; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9825 |
SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9826 |
int write_fd = -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9827 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9828 |
# if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9829 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9830 |
unsigned int parent_process_id = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9831 |
size_t write_handle_as_size_t = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9832 |
size_t event_handle_as_size_t = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9833 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9834 |
if (fields.size() != 6 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9835 |
|| !ParseNaturalNumber(fields[1], &line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9836 |
|| !ParseNaturalNumber(fields[2], &index) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9837 |
|| !ParseNaturalNumber(fields[3], &parent_process_id) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9838 |
|| !ParseNaturalNumber(fields[4], &write_handle_as_size_t) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9839 |
|| !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9840 |
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9841 |
GTEST_FLAG(internal_run_death_test)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9842 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9843 |
write_fd = GetStatusFileDescriptor(parent_process_id, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9844 |
write_handle_as_size_t, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9845 |
event_handle_as_size_t); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9846 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9847 |
# elif GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9848 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9849 |
if (fields.size() != 3 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9850 |
|| !ParseNaturalNumber(fields[1], &line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9851 |
|| !ParseNaturalNumber(fields[2], &index)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9852 |
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9853 |
+ GTEST_FLAG(internal_run_death_test)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9854 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9855 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9856 |
# else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9857 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9858 |
if (fields.size() != 4 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9859 |
|| !ParseNaturalNumber(fields[1], &line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9860 |
|| !ParseNaturalNumber(fields[2], &index) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9861 |
|| !ParseNaturalNumber(fields[3], &write_fd)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9862 |
DeathTestAbort("Bad --gtest_internal_run_death_test flag: " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9863 |
+ GTEST_FLAG(internal_run_death_test)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9864 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9865 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9866 |
# endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9867 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9868 |
return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9869 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9870 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9871 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9872 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9873 |
#endif // GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9874 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9875 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9876 |
// Copyright 2008, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9877 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9878 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9879 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9880 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9881 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9882 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9883 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9884 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9885 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9886 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9887 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9888 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9889 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9890 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9891 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9892 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9893 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9894 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9895 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9896 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9897 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9898 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9899 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9900 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9901 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9902 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9903 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9904 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9905 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9906 |
#include <stdlib.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9907 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9908 |
#if GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9909 |
# include <windows.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9910 |
#elif GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9911 |
# include <direct.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9912 |
# include <io.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9913 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9914 |
# include <limits.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9915 |
# include <climits> // Some Linux distributions define PATH_MAX here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9916 |
#endif // GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9917 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9918 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9919 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9920 |
# define GTEST_PATH_MAX_ _MAX_PATH |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9921 |
#elif defined(PATH_MAX) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9922 |
# define GTEST_PATH_MAX_ PATH_MAX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9923 |
#elif defined(_XOPEN_PATH_MAX) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9924 |
# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9925 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9926 |
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9927 |
#endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9928 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9929 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9930 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9931 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9932 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9933 |
// On Windows, '\\' is the standard path separator, but many tools and the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9934 |
// Windows API also accept '/' as an alternate path separator. Unless otherwise |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9935 |
// noted, a file path can contain either kind of path separators, or a mixture |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9936 |
// of them. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9937 |
const char kPathSeparator = '\\'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9938 |
const char kAlternatePathSeparator = '/'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9939 |
const char kAlternatePathSeparatorString[] = "/"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9940 |
# if GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9941 |
// Windows CE doesn't have a current directory. You should not use |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9942 |
// the current directory in tests on Windows CE, but this at least |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9943 |
// provides a reasonable fallback. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9944 |
const char kCurrentDirectoryString[] = "\\"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9945 |
// Windows CE doesn't define INVALID_FILE_ATTRIBUTES |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9946 |
const DWORD kInvalidFileAttributes = 0xffffffff; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9947 |
# else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9948 |
const char kCurrentDirectoryString[] = ".\\"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9949 |
# endif // GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9950 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9951 |
const char kPathSeparator = '/'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9952 |
const char kCurrentDirectoryString[] = "./"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9953 |
#endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9954 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9955 |
// Returns whether the given character is a valid path separator. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9956 |
static bool IsPathSeparator(char c) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9957 |
#if GTEST_HAS_ALT_PATH_SEP_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9958 |
return (c == kPathSeparator) || (c == kAlternatePathSeparator); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9959 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9960 |
return c == kPathSeparator; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9961 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9962 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9963 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9964 |
// Returns the current working directory, or "" if unsuccessful. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9965 |
FilePath FilePath::GetCurrentDir() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9966 |
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9967 |
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32 || \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9968 |
GTEST_OS_XTENSA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9969 |
// These platforms do not have a current directory, so we just return |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9970 |
// something reasonable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9971 |
return FilePath(kCurrentDirectoryString); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9972 |
#elif GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9973 |
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9974 |
return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9975 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9976 |
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9977 |
char* result = getcwd(cwd, sizeof(cwd)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9978 |
# if GTEST_OS_NACL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9979 |
// getcwd will likely fail in NaCl due to the sandbox, so return something |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9980 |
// reasonable. The user may have provided a shim implementation for getcwd, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9981 |
// however, so fallback only when failure is detected. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9982 |
return FilePath(result == nullptr ? kCurrentDirectoryString : cwd); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9983 |
# endif // GTEST_OS_NACL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9984 |
return FilePath(result == nullptr ? "" : cwd); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9985 |
#endif // GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9986 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9987 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9988 |
// Returns a copy of the FilePath with the case-insensitive extension removed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9989 |
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9990 |
// FilePath("dir/file"). If a case-insensitive extension is not |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9991 |
// found, returns a copy of the original FilePath. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9992 |
FilePath FilePath::RemoveExtension(const char* extension) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9993 |
const std::string dot_extension = std::string(".") + extension; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9994 |
if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9995 |
return FilePath(pathname_.substr( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9996 |
0, pathname_.length() - dot_extension.length())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9997 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9998 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9999 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10000 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10001 |
// Returns a pointer to the last occurrence of a valid path separator in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10002 |
// the FilePath. On Windows, for example, both '/' and '\' are valid path |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10003 |
// separators. Returns NULL if no path separator was found. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10004 |
const char* FilePath::FindLastPathSeparator() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10005 |
const char* const last_sep = strrchr(c_str(), kPathSeparator); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10006 |
#if GTEST_HAS_ALT_PATH_SEP_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10007 |
const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10008 |
// Comparing two pointers of which only one is NULL is undefined. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10009 |
if (last_alt_sep != nullptr && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10010 |
(last_sep == nullptr || last_alt_sep > last_sep)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10011 |
return last_alt_sep; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10012 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10013 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10014 |
return last_sep; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10015 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10016 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10017 |
// Returns a copy of the FilePath with the directory part removed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10018 |
// Example: FilePath("path/to/file").RemoveDirectoryName() returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10019 |
// FilePath("file"). If there is no directory part ("just_a_file"), it returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10020 |
// the FilePath unmodified. If there is no file part ("just_a_dir/") it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10021 |
// returns an empty FilePath (""). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10022 |
// On Windows platform, '\' is the path separator, otherwise it is '/'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10023 |
FilePath FilePath::RemoveDirectoryName() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10024 |
const char* const last_sep = FindLastPathSeparator(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10025 |
return last_sep ? FilePath(last_sep + 1) : *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10026 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10027 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10028 |
// RemoveFileName returns the directory path with the filename removed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10029 |
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10030 |
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10031 |
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10032 |
// not have a file, like "just/a/dir/", it returns the FilePath unmodified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10033 |
// On Windows platform, '\' is the path separator, otherwise it is '/'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10034 |
FilePath FilePath::RemoveFileName() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10035 |
const char* const last_sep = FindLastPathSeparator(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10036 |
std::string dir; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10037 |
if (last_sep) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10038 |
dir = std::string(c_str(), static_cast<size_t>(last_sep + 1 - c_str())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10039 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10040 |
dir = kCurrentDirectoryString; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10041 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10042 |
return FilePath(dir); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10043 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10044 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10045 |
// Helper functions for naming files in a directory for xml output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10046 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10047 |
// Given directory = "dir", base_name = "test", number = 0, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10048 |
// extension = "xml", returns "dir/test.xml". If number is greater |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10049 |
// than zero (e.g., 12), returns "dir/test_12.xml". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10050 |
// On Windows platform, uses \ as the separator rather than /. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10051 |
FilePath FilePath::MakeFileName(const FilePath& directory, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10052 |
const FilePath& base_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10053 |
int number, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10054 |
const char* extension) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10055 |
std::string file; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10056 |
if (number == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10057 |
file = base_name.string() + "." + extension; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10058 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10059 |
file = base_name.string() + "_" + StreamableToString(number) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10060 |
+ "." + extension; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10061 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10062 |
return ConcatPaths(directory, FilePath(file)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10063 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10064 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10065 |
// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10066 |
// On Windows, uses \ as the separator rather than /. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10067 |
FilePath FilePath::ConcatPaths(const FilePath& directory, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10068 |
const FilePath& relative_path) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10069 |
if (directory.IsEmpty()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10070 |
return relative_path; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10071 |
const FilePath dir(directory.RemoveTrailingPathSeparator()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10072 |
return FilePath(dir.string() + kPathSeparator + relative_path.string()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10073 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10074 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10075 |
// Returns true if pathname describes something findable in the file-system, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10076 |
// either a file, directory, or whatever. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10077 |
bool FilePath::FileOrDirectoryExists() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10078 |
#if GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10079 |
LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10080 |
const DWORD attributes = GetFileAttributes(unicode); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10081 |
delete [] unicode; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10082 |
return attributes != kInvalidFileAttributes; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10083 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10084 |
posix::StatStruct file_stat; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10085 |
return posix::Stat(pathname_.c_str(), &file_stat) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10086 |
#endif // GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10087 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10088 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10089 |
// Returns true if pathname describes a directory in the file-system |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10090 |
// that exists. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10091 |
bool FilePath::DirectoryExists() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10092 |
bool result = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10093 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10094 |
// Don't strip off trailing separator if path is a root directory on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10095 |
// Windows (like "C:\\"). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10096 |
const FilePath& path(IsRootDirectory() ? *this : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10097 |
RemoveTrailingPathSeparator()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10098 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10099 |
const FilePath& path(*this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10100 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10101 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10102 |
#if GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10103 |
LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10104 |
const DWORD attributes = GetFileAttributes(unicode); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10105 |
delete [] unicode; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10106 |
if ((attributes != kInvalidFileAttributes) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10107 |
(attributes & FILE_ATTRIBUTE_DIRECTORY)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10108 |
result = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10109 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10110 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10111 |
posix::StatStruct file_stat; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10112 |
result = posix::Stat(path.c_str(), &file_stat) == 0 && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10113 |
posix::IsDir(file_stat); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10114 |
#endif // GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10115 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10116 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10117 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10118 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10119 |
// Returns true if pathname describes a root directory. (Windows has one |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10120 |
// root directory per disk drive.) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10121 |
bool FilePath::IsRootDirectory() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10122 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10123 |
return pathname_.length() == 3 && IsAbsolutePath(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10124 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10125 |
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10126 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10127 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10128 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10129 |
// Returns true if pathname describes an absolute path. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10130 |
bool FilePath::IsAbsolutePath() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10131 |
const char* const name = pathname_.c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10132 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10133 |
return pathname_.length() >= 3 && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10134 |
((name[0] >= 'a' && name[0] <= 'z') || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10135 |
(name[0] >= 'A' && name[0] <= 'Z')) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10136 |
name[1] == ':' && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10137 |
IsPathSeparator(name[2]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10138 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10139 |
return IsPathSeparator(name[0]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10140 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10141 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10142 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10143 |
// Returns a pathname for a file that does not currently exist. The pathname |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10144 |
// will be directory/base_name.extension or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10145 |
// directory/base_name_<number>.extension if directory/base_name.extension |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10146 |
// already exists. The number will be incremented until a pathname is found |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10147 |
// that does not already exist. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10148 |
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10149 |
// There could be a race condition if two or more processes are calling this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10150 |
// function at the same time -- they could both pick the same filename. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10151 |
FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10152 |
const FilePath& base_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10153 |
const char* extension) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10154 |
FilePath full_pathname; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10155 |
int number = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10156 |
do { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10157 |
full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10158 |
} while (full_pathname.FileOrDirectoryExists()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10159 |
return full_pathname; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10160 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10161 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10162 |
// Returns true if FilePath ends with a path separator, which indicates that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10163 |
// it is intended to represent a directory. Returns false otherwise. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10164 |
// This does NOT check that a directory (or file) actually exists. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10165 |
bool FilePath::IsDirectory() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10166 |
return !pathname_.empty() && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10167 |
IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10168 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10169 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10170 |
// Create directories so that path exists. Returns true if successful or if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10171 |
// the directories already exist; returns false if unable to create directories |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10172 |
// for any reason. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10173 |
bool FilePath::CreateDirectoriesRecursively() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10174 |
if (!this->IsDirectory()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10175 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10176 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10177 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10178 |
if (pathname_.length() == 0 || this->DirectoryExists()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10179 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10180 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10181 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10182 |
const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10183 |
return parent.CreateDirectoriesRecursively() && this->CreateFolder(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10184 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10185 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10186 |
// Create the directory so that path exists. Returns true if successful or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10187 |
// if the directory already exists; returns false if unable to create the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10188 |
// directory for any reason, including if the parent directory does not |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10189 |
// exist. Not named "CreateDirectory" because that's a macro on Windows. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10190 |
bool FilePath::CreateFolder() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10191 |
#if GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10192 |
FilePath removed_sep(this->RemoveTrailingPathSeparator()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10193 |
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10194 |
int result = CreateDirectory(unicode, nullptr) ? 0 : -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10195 |
delete [] unicode; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10196 |
#elif GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10197 |
int result = _mkdir(pathname_.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10198 |
#elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10199 |
// do nothing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10200 |
int result = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10201 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10202 |
int result = mkdir(pathname_.c_str(), 0777); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10203 |
#endif // GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10204 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10205 |
if (result == -1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10206 |
return this->DirectoryExists(); // An error is OK if the directory exists. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10207 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10208 |
return true; // No error. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10209 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10210 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10211 |
// If input name has a trailing separator character, remove it and return the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10212 |
// name, otherwise return the name string unmodified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10213 |
// On Windows platform, uses \ as the separator, other platforms use /. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10214 |
FilePath FilePath::RemoveTrailingPathSeparator() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10215 |
return IsDirectory() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10216 |
? FilePath(pathname_.substr(0, pathname_.length() - 1)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10217 |
: *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10218 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10219 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10220 |
// Removes any redundant separators that might be in the pathname. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10221 |
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10222 |
// redundancies that might be in a pathname involving "." or "..". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10223 |
void FilePath::Normalize() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10224 |
auto out = pathname_.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10225 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10226 |
for (const char character : pathname_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10227 |
if (!IsPathSeparator(character)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10228 |
*(out++) = character; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10229 |
} else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10230 |
*(out++) = kPathSeparator; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10231 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10232 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10233 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10234 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10235 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10236 |
pathname_.erase(out, pathname_.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10237 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10238 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10239 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10240 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10241 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10242 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10243 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10244 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10245 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10246 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10247 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10248 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10249 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10250 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10251 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10252 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10253 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10254 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10255 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10256 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10257 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10258 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10259 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10260 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10261 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10262 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10263 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10264 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10265 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10266 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10267 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10268 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10269 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10270 |
// The Google C++ Testing and Mocking Framework (Google Test) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10271 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10272 |
// This file implements just enough of the matcher interface to allow |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10273 |
// EXPECT_DEATH and friends to accept a matcher argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10274 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10275 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10276 |
#include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10277 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10278 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10279 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10280 |
// Constructs a matcher that matches a const std::string& whose value is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10281 |
// equal to s. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10282 |
Matcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10283 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10284 |
// Constructs a matcher that matches a const std::string& whose value is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10285 |
// equal to s. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10286 |
Matcher<const std::string&>::Matcher(const char* s) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10287 |
*this = Eq(std::string(s)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10288 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10289 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10290 |
// Constructs a matcher that matches a std::string whose value is equal to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10291 |
// s. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10292 |
Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10293 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10294 |
// Constructs a matcher that matches a std::string whose value is equal to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10295 |
// s. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10296 |
Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10297 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10298 |
#if GTEST_INTERNAL_HAS_STRING_VIEW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10299 |
// Constructs a matcher that matches a const StringView& whose value is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10300 |
// equal to s. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10301 |
Matcher<const internal::StringView&>::Matcher(const std::string& s) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10302 |
*this = Eq(s); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10303 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10304 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10305 |
// Constructs a matcher that matches a const StringView& whose value is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10306 |
// equal to s. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10307 |
Matcher<const internal::StringView&>::Matcher(const char* s) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10308 |
*this = Eq(std::string(s)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10309 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10310 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10311 |
// Constructs a matcher that matches a const StringView& whose value is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10312 |
// equal to s. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10313 |
Matcher<const internal::StringView&>::Matcher(internal::StringView s) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10314 |
*this = Eq(std::string(s)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10315 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10316 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10317 |
// Constructs a matcher that matches a StringView whose value is equal to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10318 |
// s. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10319 |
Matcher<internal::StringView>::Matcher(const std::string& s) { *this = Eq(s); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10320 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10321 |
// Constructs a matcher that matches a StringView whose value is equal to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10322 |
// s. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10323 |
Matcher<internal::StringView>::Matcher(const char* s) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10324 |
*this = Eq(std::string(s)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10325 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10326 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10327 |
// Constructs a matcher that matches a StringView whose value is equal to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10328 |
// s. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10329 |
Matcher<internal::StringView>::Matcher(internal::StringView s) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10330 |
*this = Eq(std::string(s)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10331 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10332 |
#endif // GTEST_INTERNAL_HAS_STRING_VIEW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10333 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10334 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10335 |
// Copyright 2008, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10336 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10337 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10338 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10339 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10340 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10341 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10342 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10343 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10344 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10345 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10346 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10347 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10348 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10349 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10350 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10351 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10352 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10353 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10354 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10355 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10356 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10357 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10358 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10359 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10360 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10361 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10362 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10363 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10364 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10365 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10366 |
#include <limits.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10367 |
#include <stdio.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10368 |
#include <stdlib.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10369 |
#include <string.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10370 |
#include <cstdint> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10371 |
#include <fstream> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10372 |
#include <memory> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10373 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10374 |
#if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10375 |
# include <windows.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10376 |
# include <io.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10377 |
# include <sys/stat.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10378 |
# include <map> // Used in ThreadLocal. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10379 |
# ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10380 |
# include <crtdbg.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10381 |
# endif // _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10382 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10383 |
# include <unistd.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10384 |
#endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10385 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10386 |
#if GTEST_OS_MAC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10387 |
# include <mach/mach_init.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10388 |
# include <mach/task.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10389 |
# include <mach/vm_map.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10390 |
#endif // GTEST_OS_MAC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10391 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10392 |
#if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10393 |
GTEST_OS_NETBSD || GTEST_OS_OPENBSD |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10394 |
# include <sys/sysctl.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10395 |
# if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10396 |
# include <sys/user.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10397 |
# endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10398 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10399 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10400 |
#if GTEST_OS_QNX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10401 |
# include <devctl.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10402 |
# include <fcntl.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10403 |
# include <sys/procfs.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10404 |
#endif // GTEST_OS_QNX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10405 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10406 |
#if GTEST_OS_AIX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10407 |
# include <procinfo.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10408 |
# include <sys/types.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10409 |
#endif // GTEST_OS_AIX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10410 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10411 |
#if GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10412 |
# include <zircon/process.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10413 |
# include <zircon/syscalls.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10414 |
#endif // GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10415 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10416 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10417 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10418 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10419 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10420 |
#if defined(_MSC_VER) || defined(__BORLANDC__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10421 |
// MSVC and C++Builder do not provide a definition of STDERR_FILENO. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10422 |
const int kStdOutFileno = 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10423 |
const int kStdErrFileno = 2; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10424 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10425 |
const int kStdOutFileno = STDOUT_FILENO; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10426 |
const int kStdErrFileno = STDERR_FILENO; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10427 |
#endif // _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10428 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10429 |
#if GTEST_OS_LINUX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10430 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10431 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10432 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10433 |
T ReadProcFileField(const std::string& filename, int field) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10434 |
std::string dummy; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10435 |
std::ifstream file(filename.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10436 |
while (field-- > 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10437 |
file >> dummy; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10438 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10439 |
T output = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10440 |
file >> output; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10441 |
return output; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10442 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10443 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10444 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10445 |
// Returns the number of active threads, or 0 when there is an error. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10446 |
size_t GetThreadCount() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10447 |
const std::string filename = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10448 |
(Message() << "/proc/" << getpid() << "/stat").GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10449 |
return ReadProcFileField<size_t>(filename, 19); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10450 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10451 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10452 |
#elif GTEST_OS_MAC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10453 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10454 |
size_t GetThreadCount() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10455 |
const task_t task = mach_task_self(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10456 |
mach_msg_type_number_t thread_count; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10457 |
thread_act_array_t thread_list; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10458 |
const kern_return_t status = task_threads(task, &thread_list, &thread_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10459 |
if (status == KERN_SUCCESS) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10460 |
// task_threads allocates resources in thread_list and we need to free them |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10461 |
// to avoid leaks. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10462 |
vm_deallocate(task, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10463 |
reinterpret_cast<vm_address_t>(thread_list), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10464 |
sizeof(thread_t) * thread_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10465 |
return static_cast<size_t>(thread_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10466 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10467 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10468 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10469 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10470 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10471 |
#elif GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10472 |
GTEST_OS_NETBSD |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10473 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10474 |
#if GTEST_OS_NETBSD |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10475 |
#undef KERN_PROC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10476 |
#define KERN_PROC KERN_PROC2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10477 |
#define kinfo_proc kinfo_proc2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10478 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10479 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10480 |
#if GTEST_OS_DRAGONFLY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10481 |
#define KP_NLWP(kp) (kp.kp_nthreads) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10482 |
#elif GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10483 |
#define KP_NLWP(kp) (kp.ki_numthreads) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10484 |
#elif GTEST_OS_NETBSD |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10485 |
#define KP_NLWP(kp) (kp.p_nlwps) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10486 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10487 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10488 |
// Returns the number of threads running in the process, or 0 to indicate that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10489 |
// we cannot detect it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10490 |
size_t GetThreadCount() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10491 |
int mib[] = { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10492 |
CTL_KERN, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10493 |
KERN_PROC, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10494 |
KERN_PROC_PID, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10495 |
getpid(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10496 |
#if GTEST_OS_NETBSD |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10497 |
sizeof(struct kinfo_proc), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10498 |
1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10499 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10500 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10501 |
u_int miblen = sizeof(mib) / sizeof(mib[0]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10502 |
struct kinfo_proc info; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10503 |
size_t size = sizeof(info); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10504 |
if (sysctl(mib, miblen, &info, &size, NULL, 0)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10505 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10506 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10507 |
return static_cast<size_t>(KP_NLWP(info)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10508 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10509 |
#elif GTEST_OS_OPENBSD |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10510 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10511 |
// Returns the number of threads running in the process, or 0 to indicate that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10512 |
// we cannot detect it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10513 |
size_t GetThreadCount() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10514 |
int mib[] = { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10515 |
CTL_KERN, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10516 |
KERN_PROC, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10517 |
KERN_PROC_PID | KERN_PROC_SHOW_THREADS, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10518 |
getpid(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10519 |
sizeof(struct kinfo_proc), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10520 |
0, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10521 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10522 |
u_int miblen = sizeof(mib) / sizeof(mib[0]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10523 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10524 |
// get number of structs |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10525 |
size_t size; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10526 |
if (sysctl(mib, miblen, NULL, &size, NULL, 0)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10527 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10528 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10529 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10530 |
mib[5] = static_cast<int>(size / static_cast<size_t>(mib[4])); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10531 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10532 |
// populate array of structs |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10533 |
struct kinfo_proc info[mib[5]]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10534 |
if (sysctl(mib, miblen, &info, &size, NULL, 0)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10535 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10536 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10537 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10538 |
// exclude empty members |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10539 |
size_t nthreads = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10540 |
for (size_t i = 0; i < size / static_cast<size_t>(mib[4]); i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10541 |
if (info[i].p_tid != -1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10542 |
nthreads++; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10543 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10544 |
return nthreads; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10545 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10546 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10547 |
#elif GTEST_OS_QNX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10548 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10549 |
// Returns the number of threads running in the process, or 0 to indicate that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10550 |
// we cannot detect it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10551 |
size_t GetThreadCount() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10552 |
const int fd = open("/proc/self/as", O_RDONLY); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10553 |
if (fd < 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10554 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10555 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10556 |
procfs_info process_info; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10557 |
const int status = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10558 |
devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10559 |
close(fd); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10560 |
if (status == EOK) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10561 |
return static_cast<size_t>(process_info.num_threads); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10562 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10563 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10564 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10565 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10566 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10567 |
#elif GTEST_OS_AIX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10568 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10569 |
size_t GetThreadCount() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10570 |
struct procentry64 entry; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10571 |
pid_t pid = getpid(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10572 |
int status = getprocs64(&entry, sizeof(entry), nullptr, 0, &pid, 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10573 |
if (status == 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10574 |
return entry.pi_thcount; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10575 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10576 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10577 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10578 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10579 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10580 |
#elif GTEST_OS_FUCHSIA |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10581 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10582 |
size_t GetThreadCount() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10583 |
int dummy_buffer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10584 |
size_t avail; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10585 |
zx_status_t status = zx_object_get_info( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10586 |
zx_process_self(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10587 |
ZX_INFO_PROCESS_THREADS, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10588 |
&dummy_buffer, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10589 |
0, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10590 |
nullptr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10591 |
&avail); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10592 |
if (status == ZX_OK) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10593 |
return avail; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10594 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10595 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10596 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10597 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10598 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10599 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10600 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10601 |
size_t GetThreadCount() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10602 |
// There's no portable way to detect the number of threads, so we just |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10603 |
// return 0 to indicate that we cannot detect it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10604 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10605 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10606 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10607 |
#endif // GTEST_OS_LINUX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10608 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10609 |
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10610 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10611 |
void SleepMilliseconds(int n) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10612 |
::Sleep(static_cast<DWORD>(n)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10613 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10614 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10615 |
AutoHandle::AutoHandle() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10616 |
: handle_(INVALID_HANDLE_VALUE) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10617 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10618 |
AutoHandle::AutoHandle(Handle handle) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10619 |
: handle_(handle) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10620 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10621 |
AutoHandle::~AutoHandle() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10622 |
Reset(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10623 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10624 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10625 |
AutoHandle::Handle AutoHandle::Get() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10626 |
return handle_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10627 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10628 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10629 |
void AutoHandle::Reset() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10630 |
Reset(INVALID_HANDLE_VALUE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10631 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10632 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10633 |
void AutoHandle::Reset(HANDLE handle) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10634 |
// Resetting with the same handle we already own is invalid. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10635 |
if (handle_ != handle) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10636 |
if (IsCloseable()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10637 |
::CloseHandle(handle_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10638 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10639 |
handle_ = handle; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10640 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10641 |
GTEST_CHECK_(!IsCloseable()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10642 |
<< "Resetting a valid handle to itself is likely a programmer error " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10643 |
"and thus not allowed."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10644 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10645 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10646 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10647 |
bool AutoHandle::IsCloseable() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10648 |
// Different Windows APIs may use either of these values to represent an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10649 |
// invalid handle. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10650 |
return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10651 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10652 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10653 |
Notification::Notification() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10654 |
: event_(::CreateEvent(nullptr, // Default security attributes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10655 |
TRUE, // Do not reset automatically. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10656 |
FALSE, // Initially unset. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10657 |
nullptr)) { // Anonymous event. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10658 |
GTEST_CHECK_(event_.Get() != nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10659 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10660 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10661 |
void Notification::Notify() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10662 |
GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10663 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10664 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10665 |
void Notification::WaitForNotification() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10666 |
GTEST_CHECK_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10667 |
::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10668 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10669 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10670 |
Mutex::Mutex() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10671 |
: owner_thread_id_(0), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10672 |
type_(kDynamic), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10673 |
critical_section_init_phase_(0), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10674 |
critical_section_(new CRITICAL_SECTION) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10675 |
::InitializeCriticalSection(critical_section_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10676 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10677 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10678 |
Mutex::~Mutex() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10679 |
// Static mutexes are leaked intentionally. It is not thread-safe to try |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10680 |
// to clean them up. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10681 |
if (type_ == kDynamic) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10682 |
::DeleteCriticalSection(critical_section_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10683 |
delete critical_section_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10684 |
critical_section_ = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10685 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10686 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10687 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10688 |
void Mutex::Lock() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10689 |
ThreadSafeLazyInit(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10690 |
::EnterCriticalSection(critical_section_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10691 |
owner_thread_id_ = ::GetCurrentThreadId(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10692 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10693 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10694 |
void Mutex::Unlock() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10695 |
ThreadSafeLazyInit(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10696 |
// We don't protect writing to owner_thread_id_ here, as it's the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10697 |
// caller's responsibility to ensure that the current thread holds the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10698 |
// mutex when this is called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10699 |
owner_thread_id_ = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10700 |
::LeaveCriticalSection(critical_section_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10701 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10702 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10703 |
// Does nothing if the current thread holds the mutex. Otherwise, crashes |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10704 |
// with high probability. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10705 |
void Mutex::AssertHeld() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10706 |
ThreadSafeLazyInit(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10707 |
GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10708 |
<< "The current thread is not holding the mutex @" << this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10709 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10710 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10711 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10712 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10713 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10714 |
// Use the RAII idiom to flag mem allocs that are intentionally never |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10715 |
// deallocated. The motivation is to silence the false positive mem leaks |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10716 |
// that are reported by the debug version of MS's CRT which can only detect |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10717 |
// if an alloc is missing a matching deallocation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10718 |
// Example: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10719 |
// MemoryIsNotDeallocated memory_is_not_deallocated; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10720 |
// critical_section_ = new CRITICAL_SECTION; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10721 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10722 |
class MemoryIsNotDeallocated |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10723 |
{ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10724 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10725 |
MemoryIsNotDeallocated() : old_crtdbg_flag_(0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10726 |
old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10727 |
// Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10728 |
// doesn't report mem leak if there's no matching deallocation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10729 |
_CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10730 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10731 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10732 |
~MemoryIsNotDeallocated() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10733 |
// Restore the original _CRTDBG_ALLOC_MEM_DF flag |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10734 |
_CrtSetDbgFlag(old_crtdbg_flag_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10735 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10736 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10737 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10738 |
int old_crtdbg_flag_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10739 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10740 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(MemoryIsNotDeallocated); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10741 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10742 |
#endif // _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10743 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10744 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10745 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10746 |
// Initializes owner_thread_id_ and critical_section_ in static mutexes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10747 |
void Mutex::ThreadSafeLazyInit() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10748 |
// Dynamic mutexes are initialized in the constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10749 |
if (type_ == kStatic) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10750 |
switch ( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10751 |
::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10752 |
case 0: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10753 |
// If critical_section_init_phase_ was 0 before the exchange, we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10754 |
// are the first to test it and need to perform the initialization. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10755 |
owner_thread_id_ = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10756 |
{ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10757 |
// Use RAII to flag that following mem alloc is never deallocated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10758 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10759 |
MemoryIsNotDeallocated memory_is_not_deallocated; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10760 |
#endif // _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10761 |
critical_section_ = new CRITICAL_SECTION; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10762 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10763 |
::InitializeCriticalSection(critical_section_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10764 |
// Updates the critical_section_init_phase_ to 2 to signal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10765 |
// initialization complete. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10766 |
GTEST_CHECK_(::InterlockedCompareExchange( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10767 |
&critical_section_init_phase_, 2L, 1L) == |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10768 |
1L); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10769 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10770 |
case 1: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10771 |
// Somebody else is already initializing the mutex; spin until they |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10772 |
// are done. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10773 |
while (::InterlockedCompareExchange(&critical_section_init_phase_, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10774 |
2L, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10775 |
2L) != 2L) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10776 |
// Possibly yields the rest of the thread's time slice to other |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10777 |
// threads. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10778 |
::Sleep(0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10779 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10780 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10781 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10782 |
case 2: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10783 |
break; // The mutex is already initialized and ready for use. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10784 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10785 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10786 |
GTEST_CHECK_(false) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10787 |
<< "Unexpected value of critical_section_init_phase_ " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10788 |
<< "while initializing a static mutex."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10789 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10790 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10791 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10792 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10793 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10794 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10795 |
class ThreadWithParamSupport : public ThreadWithParamBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10796 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10797 |
static HANDLE CreateThread(Runnable* runnable, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10798 |
Notification* thread_can_start) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10799 |
ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10800 |
DWORD thread_id; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10801 |
HANDLE thread_handle = ::CreateThread( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10802 |
nullptr, // Default security. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10803 |
0, // Default stack size. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10804 |
&ThreadWithParamSupport::ThreadMain, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10805 |
param, // Parameter to ThreadMainStatic |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10806 |
0x0, // Default creation flags. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10807 |
&thread_id); // Need a valid pointer for the call to work under Win98. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10808 |
GTEST_CHECK_(thread_handle != nullptr) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10809 |
<< "CreateThread failed with error " << ::GetLastError() << "."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10810 |
if (thread_handle == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10811 |
delete param; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10812 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10813 |
return thread_handle; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10814 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10815 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10816 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10817 |
struct ThreadMainParam { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10818 |
ThreadMainParam(Runnable* runnable, Notification* thread_can_start) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10819 |
: runnable_(runnable), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10820 |
thread_can_start_(thread_can_start) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10821 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10822 |
std::unique_ptr<Runnable> runnable_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10823 |
// Does not own. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10824 |
Notification* thread_can_start_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10825 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10826 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10827 |
static DWORD WINAPI ThreadMain(void* ptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10828 |
// Transfers ownership. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10829 |
std::unique_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10830 |
if (param->thread_can_start_ != nullptr) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10831 |
param->thread_can_start_->WaitForNotification(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10832 |
param->runnable_->Run(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10833 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10834 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10835 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10836 |
// Prohibit instantiation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10837 |
ThreadWithParamSupport(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10838 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10839 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10840 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10841 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10842 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10843 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10844 |
ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10845 |
Notification* thread_can_start) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10846 |
: thread_(ThreadWithParamSupport::CreateThread(runnable, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10847 |
thread_can_start)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10848 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10849 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10850 |
ThreadWithParamBase::~ThreadWithParamBase() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10851 |
Join(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10852 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10853 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10854 |
void ThreadWithParamBase::Join() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10855 |
GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10856 |
<< "Failed to join the thread with error " << ::GetLastError() << "."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10857 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10858 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10859 |
// Maps a thread to a set of ThreadIdToThreadLocals that have values |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10860 |
// instantiated on that thread and notifies them when the thread exits. A |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10861 |
// ThreadLocal instance is expected to persist until all threads it has |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10862 |
// values on have terminated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10863 |
class ThreadLocalRegistryImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10864 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10865 |
// Registers thread_local_instance as having value on the current thread. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10866 |
// Returns a value that can be used to identify the thread from other threads. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10867 |
static ThreadLocalValueHolderBase* GetValueOnCurrentThread( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10868 |
const ThreadLocalBase* thread_local_instance) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10869 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10870 |
MemoryIsNotDeallocated memory_is_not_deallocated; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10871 |
#endif // _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10872 |
DWORD current_thread = ::GetCurrentThreadId(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10873 |
MutexLock lock(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10874 |
ThreadIdToThreadLocals* const thread_to_thread_locals = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10875 |
GetThreadLocalsMapLocked(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10876 |
ThreadIdToThreadLocals::iterator thread_local_pos = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10877 |
thread_to_thread_locals->find(current_thread); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10878 |
if (thread_local_pos == thread_to_thread_locals->end()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10879 |
thread_local_pos = thread_to_thread_locals->insert( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10880 |
std::make_pair(current_thread, ThreadLocalValues())).first; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10881 |
StartWatcherThreadFor(current_thread); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10882 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10883 |
ThreadLocalValues& thread_local_values = thread_local_pos->second; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10884 |
ThreadLocalValues::iterator value_pos = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10885 |
thread_local_values.find(thread_local_instance); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10886 |
if (value_pos == thread_local_values.end()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10887 |
value_pos = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10888 |
thread_local_values |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10889 |
.insert(std::make_pair( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10890 |
thread_local_instance, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10891 |
std::shared_ptr<ThreadLocalValueHolderBase>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10892 |
thread_local_instance->NewValueForCurrentThread()))) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10893 |
.first; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10894 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10895 |
return value_pos->second.get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10896 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10897 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10898 |
static void OnThreadLocalDestroyed( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10899 |
const ThreadLocalBase* thread_local_instance) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10900 |
std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10901 |
// Clean up the ThreadLocalValues data structure while holding the lock, but |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10902 |
// defer the destruction of the ThreadLocalValueHolderBases. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10903 |
{ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10904 |
MutexLock lock(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10905 |
ThreadIdToThreadLocals* const thread_to_thread_locals = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10906 |
GetThreadLocalsMapLocked(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10907 |
for (ThreadIdToThreadLocals::iterator it = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10908 |
thread_to_thread_locals->begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10909 |
it != thread_to_thread_locals->end(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10910 |
++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10911 |
ThreadLocalValues& thread_local_values = it->second; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10912 |
ThreadLocalValues::iterator value_pos = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10913 |
thread_local_values.find(thread_local_instance); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10914 |
if (value_pos != thread_local_values.end()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10915 |
value_holders.push_back(value_pos->second); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10916 |
thread_local_values.erase(value_pos); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10917 |
// This 'if' can only be successful at most once, so theoretically we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10918 |
// could break out of the loop here, but we don't bother doing so. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10919 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10920 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10921 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10922 |
// Outside the lock, let the destructor for 'value_holders' deallocate the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10923 |
// ThreadLocalValueHolderBases. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10924 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10925 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10926 |
static void OnThreadExit(DWORD thread_id) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10927 |
GTEST_CHECK_(thread_id != 0) << ::GetLastError(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10928 |
std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10929 |
// Clean up the ThreadIdToThreadLocals data structure while holding the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10930 |
// lock, but defer the destruction of the ThreadLocalValueHolderBases. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10931 |
{ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10932 |
MutexLock lock(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10933 |
ThreadIdToThreadLocals* const thread_to_thread_locals = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10934 |
GetThreadLocalsMapLocked(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10935 |
ThreadIdToThreadLocals::iterator thread_local_pos = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10936 |
thread_to_thread_locals->find(thread_id); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10937 |
if (thread_local_pos != thread_to_thread_locals->end()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10938 |
ThreadLocalValues& thread_local_values = thread_local_pos->second; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10939 |
for (ThreadLocalValues::iterator value_pos = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10940 |
thread_local_values.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10941 |
value_pos != thread_local_values.end(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10942 |
++value_pos) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10943 |
value_holders.push_back(value_pos->second); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10944 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10945 |
thread_to_thread_locals->erase(thread_local_pos); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10946 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10947 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10948 |
// Outside the lock, let the destructor for 'value_holders' deallocate the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10949 |
// ThreadLocalValueHolderBases. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10950 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10951 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10952 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10953 |
// In a particular thread, maps a ThreadLocal object to its value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10954 |
typedef std::map<const ThreadLocalBase*, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10955 |
std::shared_ptr<ThreadLocalValueHolderBase> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10956 |
ThreadLocalValues; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10957 |
// Stores all ThreadIdToThreadLocals having values in a thread, indexed by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10958 |
// thread's ID. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10959 |
typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10960 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10961 |
// Holds the thread id and thread handle that we pass from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10962 |
// StartWatcherThreadFor to WatcherThreadFunc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10963 |
typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10964 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10965 |
static void StartWatcherThreadFor(DWORD thread_id) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10966 |
// The returned handle will be kept in thread_map and closed by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10967 |
// watcher_thread in WatcherThreadFunc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10968 |
HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10969 |
FALSE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10970 |
thread_id); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10971 |
GTEST_CHECK_(thread != nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10972 |
// We need to pass a valid thread ID pointer into CreateThread for it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10973 |
// to work correctly under Win98. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10974 |
DWORD watcher_thread_id; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10975 |
HANDLE watcher_thread = ::CreateThread( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10976 |
nullptr, // Default security. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10977 |
0, // Default stack size |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10978 |
&ThreadLocalRegistryImpl::WatcherThreadFunc, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10979 |
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10980 |
CREATE_SUSPENDED, &watcher_thread_id); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10981 |
GTEST_CHECK_(watcher_thread != nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10982 |
// Give the watcher thread the same priority as ours to avoid being |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10983 |
// blocked by it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10984 |
::SetThreadPriority(watcher_thread, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10985 |
::GetThreadPriority(::GetCurrentThread())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10986 |
::ResumeThread(watcher_thread); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10987 |
::CloseHandle(watcher_thread); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10988 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10989 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10990 |
// Monitors exit from a given thread and notifies those |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10991 |
// ThreadIdToThreadLocals about thread termination. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10992 |
static DWORD WINAPI WatcherThreadFunc(LPVOID param) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10993 |
const ThreadIdAndHandle* tah = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10994 |
reinterpret_cast<const ThreadIdAndHandle*>(param); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10995 |
GTEST_CHECK_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10996 |
::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10997 |
OnThreadExit(tah->first); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10998 |
::CloseHandle(tah->second); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10999 |
delete tah; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11000 |
return 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11001 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11002 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11003 |
// Returns map of thread local instances. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11004 |
static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11005 |
mutex_.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11006 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11007 |
MemoryIsNotDeallocated memory_is_not_deallocated; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11008 |
#endif // _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11009 |
static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11010 |
return map; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11011 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11012 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11013 |
// Protects access to GetThreadLocalsMapLocked() and its return value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11014 |
static Mutex mutex_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11015 |
// Protects access to GetThreadMapLocked() and its return value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11016 |
static Mutex thread_map_mutex_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11017 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11018 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11019 |
Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11020 |
Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11021 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11022 |
ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11023 |
const ThreadLocalBase* thread_local_instance) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11024 |
return ThreadLocalRegistryImpl::GetValueOnCurrentThread( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11025 |
thread_local_instance); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11026 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11027 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11028 |
void ThreadLocalRegistry::OnThreadLocalDestroyed( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11029 |
const ThreadLocalBase* thread_local_instance) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11030 |
ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11031 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11032 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11033 |
#endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11034 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11035 |
#if GTEST_USES_POSIX_RE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11036 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11037 |
// Implements RE. Currently only needed for death tests. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11038 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11039 |
RE::~RE() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11040 |
if (is_valid_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11041 |
// regfree'ing an invalid regex might crash because the content |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11042 |
// of the regex is undefined. Since the regex's are essentially |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11043 |
// the same, one cannot be valid (or invalid) without the other |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11044 |
// being so too. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11045 |
regfree(&partial_regex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11046 |
regfree(&full_regex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11047 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11048 |
free(const_cast<char*>(pattern_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11049 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11050 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11051 |
// Returns true if and only if regular expression re matches the entire str. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11052 |
bool RE::FullMatch(const char* str, const RE& re) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11053 |
if (!re.is_valid_) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11054 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11055 |
regmatch_t match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11056 |
return regexec(&re.full_regex_, str, 1, &match, 0) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11057 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11058 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11059 |
// Returns true if and only if regular expression re matches a substring of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11060 |
// str (including str itself). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11061 |
bool RE::PartialMatch(const char* str, const RE& re) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11062 |
if (!re.is_valid_) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11063 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11064 |
regmatch_t match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11065 |
return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11066 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11067 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11068 |
// Initializes an RE from its string representation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11069 |
void RE::Init(const char* regex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11070 |
pattern_ = posix::StrDup(regex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11071 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11072 |
// Reserves enough bytes to hold the regular expression used for a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11073 |
// full match. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11074 |
const size_t full_regex_len = strlen(regex) + 10; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11075 |
char* const full_pattern = new char[full_regex_len]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11076 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11077 |
snprintf(full_pattern, full_regex_len, "^(%s)$", regex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11078 |
is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11079 |
// We want to call regcomp(&partial_regex_, ...) even if the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11080 |
// previous expression returns false. Otherwise partial_regex_ may |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11081 |
// not be properly initialized can may cause trouble when it's |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11082 |
// freed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11083 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11084 |
// Some implementation of POSIX regex (e.g. on at least some |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11085 |
// versions of Cygwin) doesn't accept the empty string as a valid |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11086 |
// regex. We change it to an equivalent form "()" to be safe. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11087 |
if (is_valid_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11088 |
const char* const partial_regex = (*regex == '\0') ? "()" : regex; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11089 |
is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11090 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11091 |
EXPECT_TRUE(is_valid_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11092 |
<< "Regular expression \"" << regex |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11093 |
<< "\" is not a valid POSIX Extended regular expression."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11094 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11095 |
delete[] full_pattern; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11096 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11097 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11098 |
#elif GTEST_USES_SIMPLE_RE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11099 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11100 |
// Returns true if and only if ch appears anywhere in str (excluding the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11101 |
// terminating '\0' character). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11102 |
bool IsInSet(char ch, const char* str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11103 |
return ch != '\0' && strchr(str, ch) != nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11104 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11105 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11106 |
// Returns true if and only if ch belongs to the given classification. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11107 |
// Unlike similar functions in <ctype.h>, these aren't affected by the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11108 |
// current locale. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11109 |
bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11110 |
bool IsAsciiPunct(char ch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11111 |
return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11112 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11113 |
bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11114 |
bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11115 |
bool IsAsciiWordChar(char ch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11116 |
return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11117 |
('0' <= ch && ch <= '9') || ch == '_'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11118 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11119 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11120 |
// Returns true if and only if "\\c" is a supported escape sequence. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11121 |
bool IsValidEscape(char c) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11122 |
return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11123 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11124 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11125 |
// Returns true if and only if the given atom (specified by escaped and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11126 |
// pattern) matches ch. The result is undefined if the atom is invalid. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11127 |
bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11128 |
if (escaped) { // "\\p" where p is pattern_char. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11129 |
switch (pattern_char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11130 |
case 'd': return IsAsciiDigit(ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11131 |
case 'D': return !IsAsciiDigit(ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11132 |
case 'f': return ch == '\f'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11133 |
case 'n': return ch == '\n'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11134 |
case 'r': return ch == '\r'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11135 |
case 's': return IsAsciiWhiteSpace(ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11136 |
case 'S': return !IsAsciiWhiteSpace(ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11137 |
case 't': return ch == '\t'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11138 |
case 'v': return ch == '\v'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11139 |
case 'w': return IsAsciiWordChar(ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11140 |
case 'W': return !IsAsciiWordChar(ch); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11141 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11142 |
return IsAsciiPunct(pattern_char) && pattern_char == ch; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11143 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11144 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11145 |
return (pattern_char == '.' && ch != '\n') || pattern_char == ch; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11146 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11147 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11148 |
// Helper function used by ValidateRegex() to format error messages. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11149 |
static std::string FormatRegexSyntaxError(const char* regex, int index) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11150 |
return (Message() << "Syntax error at index " << index |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11151 |
<< " in simple regular expression \"" << regex << "\": ").GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11152 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11153 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11154 |
// Generates non-fatal failures and returns false if regex is invalid; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11155 |
// otherwise returns true. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11156 |
bool ValidateRegex(const char* regex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11157 |
if (regex == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11158 |
ADD_FAILURE() << "NULL is not a valid simple regular expression."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11159 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11160 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11161 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11162 |
bool is_valid = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11163 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11164 |
// True if and only if ?, *, or + can follow the previous atom. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11165 |
bool prev_repeatable = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11166 |
for (int i = 0; regex[i]; i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11167 |
if (regex[i] == '\\') { // An escape sequence |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11168 |
i++; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11169 |
if (regex[i] == '\0') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11170 |
ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11171 |
<< "'\\' cannot appear at the end."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11172 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11173 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11174 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11175 |
if (!IsValidEscape(regex[i])) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11176 |
ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11177 |
<< "invalid escape sequence \"\\" << regex[i] << "\"."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11178 |
is_valid = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11179 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11180 |
prev_repeatable = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11181 |
} else { // Not an escape sequence. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11182 |
const char ch = regex[i]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11183 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11184 |
if (ch == '^' && i > 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11185 |
ADD_FAILURE() << FormatRegexSyntaxError(regex, i) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11186 |
<< "'^' can only appear at the beginning."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11187 |
is_valid = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11188 |
} else if (ch == '$' && regex[i + 1] != '\0') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11189 |
ADD_FAILURE() << FormatRegexSyntaxError(regex, i) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11190 |
<< "'$' can only appear at the end."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11191 |
is_valid = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11192 |
} else if (IsInSet(ch, "()[]{}|")) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11193 |
ADD_FAILURE() << FormatRegexSyntaxError(regex, i) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11194 |
<< "'" << ch << "' is unsupported."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11195 |
is_valid = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11196 |
} else if (IsRepeat(ch) && !prev_repeatable) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11197 |
ADD_FAILURE() << FormatRegexSyntaxError(regex, i) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11198 |
<< "'" << ch << "' can only follow a repeatable token."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11199 |
is_valid = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11200 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11201 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11202 |
prev_repeatable = !IsInSet(ch, "^$?*+"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11203 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11204 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11205 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11206 |
return is_valid; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11207 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11208 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11209 |
// Matches a repeated regex atom followed by a valid simple regular |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11210 |
// expression. The regex atom is defined as c if escaped is false, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11211 |
// or \c otherwise. repeat is the repetition meta character (?, *, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11212 |
// or +). The behavior is undefined if str contains too many |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11213 |
// characters to be indexable by size_t, in which case the test will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11214 |
// probably time out anyway. We are fine with this limitation as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11215 |
// std::string has it too. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11216 |
bool MatchRepetitionAndRegexAtHead( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11217 |
bool escaped, char c, char repeat, const char* regex, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11218 |
const char* str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11219 |
const size_t min_count = (repeat == '+') ? 1 : 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11220 |
const size_t max_count = (repeat == '?') ? 1 : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11221 |
static_cast<size_t>(-1) - 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11222 |
// We cannot call numeric_limits::max() as it conflicts with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11223 |
// max() macro on Windows. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11224 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11225 |
for (size_t i = 0; i <= max_count; ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11226 |
// We know that the atom matches each of the first i characters in str. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11227 |
if (i >= min_count && MatchRegexAtHead(regex, str + i)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11228 |
// We have enough matches at the head, and the tail matches too. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11229 |
// Since we only care about *whether* the pattern matches str |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11230 |
// (as opposed to *how* it matches), there is no need to find a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11231 |
// greedy match. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11232 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11233 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11234 |
if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11235 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11236 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11237 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11238 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11239 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11240 |
// Returns true if and only if regex matches a prefix of str. regex must |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11241 |
// be a valid simple regular expression and not start with "^", or the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11242 |
// result is undefined. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11243 |
bool MatchRegexAtHead(const char* regex, const char* str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11244 |
if (*regex == '\0') // An empty regex matches a prefix of anything. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11245 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11246 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11247 |
// "$" only matches the end of a string. Note that regex being |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11248 |
// valid guarantees that there's nothing after "$" in it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11249 |
if (*regex == '$') |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11250 |
return *str == '\0'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11251 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11252 |
// Is the first thing in regex an escape sequence? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11253 |
const bool escaped = *regex == '\\'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11254 |
if (escaped) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11255 |
++regex; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11256 |
if (IsRepeat(regex[1])) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11257 |
// MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11258 |
// here's an indirect recursion. It terminates as the regex gets |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11259 |
// shorter in each recursion. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11260 |
return MatchRepetitionAndRegexAtHead( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11261 |
escaped, regex[0], regex[1], regex + 2, str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11262 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11263 |
// regex isn't empty, isn't "$", and doesn't start with a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11264 |
// repetition. We match the first atom of regex with the first |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11265 |
// character of str and recurse. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11266 |
return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11267 |
MatchRegexAtHead(regex + 1, str + 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11268 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11269 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11270 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11271 |
// Returns true if and only if regex matches any substring of str. regex must |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11272 |
// be a valid simple regular expression, or the result is undefined. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11273 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11274 |
// The algorithm is recursive, but the recursion depth doesn't exceed |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11275 |
// the regex length, so we won't need to worry about running out of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11276 |
// stack space normally. In rare cases the time complexity can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11277 |
// exponential with respect to the regex length + the string length, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11278 |
// but usually it's must faster (often close to linear). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11279 |
bool MatchRegexAnywhere(const char* regex, const char* str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11280 |
if (regex == nullptr || str == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11281 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11282 |
if (*regex == '^') |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11283 |
return MatchRegexAtHead(regex + 1, str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11284 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11285 |
// A successful match can be anywhere in str. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11286 |
do { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11287 |
if (MatchRegexAtHead(regex, str)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11288 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11289 |
} while (*str++ != '\0'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11290 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11291 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11292 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11293 |
// Implements the RE class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11294 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11295 |
RE::~RE() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11296 |
free(const_cast<char*>(pattern_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11297 |
free(const_cast<char*>(full_pattern_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11298 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11299 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11300 |
// Returns true if and only if regular expression re matches the entire str. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11301 |
bool RE::FullMatch(const char* str, const RE& re) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11302 |
return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11303 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11304 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11305 |
// Returns true if and only if regular expression re matches a substring of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11306 |
// str (including str itself). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11307 |
bool RE::PartialMatch(const char* str, const RE& re) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11308 |
return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11309 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11310 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11311 |
// Initializes an RE from its string representation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11312 |
void RE::Init(const char* regex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11313 |
pattern_ = full_pattern_ = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11314 |
if (regex != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11315 |
pattern_ = posix::StrDup(regex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11316 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11317 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11318 |
is_valid_ = ValidateRegex(regex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11319 |
if (!is_valid_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11320 |
// No need to calculate the full pattern when the regex is invalid. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11321 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11322 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11323 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11324 |
const size_t len = strlen(regex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11325 |
// Reserves enough bytes to hold the regular expression used for a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11326 |
// full match: we need space to prepend a '^', append a '$', and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11327 |
// terminate the string with '\0'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11328 |
char* buffer = static_cast<char*>(malloc(len + 3)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11329 |
full_pattern_ = buffer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11330 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11331 |
if (*regex != '^') |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11332 |
*buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11333 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11334 |
// We don't use snprintf or strncpy, as they trigger a warning when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11335 |
// compiled with VC++ 8.0. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11336 |
memcpy(buffer, regex, len); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11337 |
buffer += len; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11338 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11339 |
if (len == 0 || regex[len - 1] != '$') |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11340 |
*buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11341 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11342 |
*buffer = '\0'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11343 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11344 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11345 |
#endif // GTEST_USES_POSIX_RE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11346 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11347 |
const char kUnknownFile[] = "unknown file"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11348 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11349 |
// Formats a source file path and a line number as they would appear |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11350 |
// in an error message from the compiler used to compile this code. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11351 |
GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11352 |
const std::string file_name(file == nullptr ? kUnknownFile : file); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11353 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11354 |
if (line < 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11355 |
return file_name + ":"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11356 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11357 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11358 |
return file_name + "(" + StreamableToString(line) + "):"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11359 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11360 |
return file_name + ":" + StreamableToString(line) + ":"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11361 |
#endif // _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11362 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11363 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11364 |
// Formats a file location for compiler-independent XML output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11365 |
// Although this function is not platform dependent, we put it next to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11366 |
// FormatFileLocation in order to contrast the two functions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11367 |
// Note that FormatCompilerIndependentFileLocation() does NOT append colon |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11368 |
// to the file location it produces, unlike FormatFileLocation(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11369 |
GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11370 |
const char* file, int line) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11371 |
const std::string file_name(file == nullptr ? kUnknownFile : file); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11372 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11373 |
if (line < 0) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11374 |
return file_name; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11375 |
else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11376 |
return file_name + ":" + StreamableToString(line); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11377 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11378 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11379 |
GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11380 |
: severity_(severity) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11381 |
const char* const marker = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11382 |
severity == GTEST_INFO ? "[ INFO ]" : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11383 |
severity == GTEST_WARNING ? "[WARNING]" : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11384 |
severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11385 |
GetStream() << ::std::endl << marker << " " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11386 |
<< FormatFileLocation(file, line).c_str() << ": "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11387 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11388 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11389 |
// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11390 |
GTestLog::~GTestLog() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11391 |
GetStream() << ::std::endl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11392 |
if (severity_ == GTEST_FATAL) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11393 |
fflush(stderr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11394 |
posix::Abort(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11395 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11396 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11397 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11398 |
// Disable Microsoft deprecation warnings for POSIX functions called from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11399 |
// this class (creat, dup, dup2, and close) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11400 |
GTEST_DISABLE_MSC_DEPRECATED_PUSH_() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11401 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11402 |
#if GTEST_HAS_STREAM_REDIRECTION |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11403 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11404 |
// Object that captures an output stream (stdout/stderr). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11405 |
class CapturedStream { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11406 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11407 |
// The ctor redirects the stream to a temporary file. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11408 |
explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11409 |
# if GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11410 |
char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11411 |
char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11412 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11413 |
::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11414 |
const UINT success = ::GetTempFileNameA(temp_dir_path, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11415 |
"gtest_redir", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11416 |
0, // Generate unique file name. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11417 |
temp_file_path); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11418 |
GTEST_CHECK_(success != 0) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11419 |
<< "Unable to create a temporary file in " << temp_dir_path; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11420 |
const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11421 |
GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11422 |
<< temp_file_path; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11423 |
filename_ = temp_file_path; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11424 |
# else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11425 |
// There's no guarantee that a test has write access to the current |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11426 |
// directory, so we create the temporary file in the /tmp directory |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11427 |
// instead. We use /tmp on most systems, and /sdcard on Android. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11428 |
// That's because Android doesn't have /tmp. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11429 |
# if GTEST_OS_LINUX_ANDROID |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11430 |
// Note: Android applications are expected to call the framework's |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11431 |
// Context.getExternalStorageDirectory() method through JNI to get |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11432 |
// the location of the world-writable SD Card directory. However, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11433 |
// this requires a Context handle, which cannot be retrieved |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11434 |
// globally from native code. Doing so also precludes running the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11435 |
// code as part of a regular standalone executable, which doesn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11436 |
// run in a Dalvik process (e.g. when running it through 'adb shell'). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11437 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11438 |
// The location /data/local/tmp is directly accessible from native code. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11439 |
// '/sdcard' and other variants cannot be relied on, as they are not |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11440 |
// guaranteed to be mounted, or may have a delay in mounting. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11441 |
char name_template[] = "/data/local/tmp/gtest_captured_stream.XXXXXX"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11442 |
# else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11443 |
char name_template[] = "/tmp/captured_stream.XXXXXX"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11444 |
# endif // GTEST_OS_LINUX_ANDROID |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11445 |
const int captured_fd = mkstemp(name_template); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11446 |
if (captured_fd == -1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11447 |
GTEST_LOG_(WARNING) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11448 |
<< "Failed to create tmp file " << name_template |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11449 |
<< " for test; does the test have access to the /tmp directory?"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11450 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11451 |
filename_ = name_template; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11452 |
# endif // GTEST_OS_WINDOWS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11453 |
fflush(nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11454 |
dup2(captured_fd, fd_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11455 |
close(captured_fd); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11456 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11457 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11458 |
~CapturedStream() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11459 |
remove(filename_.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11460 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11461 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11462 |
std::string GetCapturedString() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11463 |
if (uncaptured_fd_ != -1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11464 |
// Restores the original stream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11465 |
fflush(nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11466 |
dup2(uncaptured_fd_, fd_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11467 |
close(uncaptured_fd_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11468 |
uncaptured_fd_ = -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11469 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11470 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11471 |
FILE* const file = posix::FOpen(filename_.c_str(), "r"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11472 |
if (file == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11473 |
GTEST_LOG_(FATAL) << "Failed to open tmp file " << filename_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11474 |
<< " for capturing stream."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11475 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11476 |
const std::string content = ReadEntireFile(file); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11477 |
posix::FClose(file); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11478 |
return content; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11479 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11480 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11481 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11482 |
const int fd_; // A stream to capture. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11483 |
int uncaptured_fd_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11484 |
// Name of the temporary file holding the stderr output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11485 |
::std::string filename_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11486 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11487 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11488 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11489 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11490 |
GTEST_DISABLE_MSC_DEPRECATED_POP_() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11491 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11492 |
static CapturedStream* g_captured_stderr = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11493 |
static CapturedStream* g_captured_stdout = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11494 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11495 |
// Starts capturing an output stream (stdout/stderr). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11496 |
static void CaptureStream(int fd, const char* stream_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11497 |
CapturedStream** stream) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11498 |
if (*stream != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11499 |
GTEST_LOG_(FATAL) << "Only one " << stream_name |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11500 |
<< " capturer can exist at a time."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11501 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11502 |
*stream = new CapturedStream(fd); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11503 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11504 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11505 |
// Stops capturing the output stream and returns the captured string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11506 |
static std::string GetCapturedStream(CapturedStream** captured_stream) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11507 |
const std::string content = (*captured_stream)->GetCapturedString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11508 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11509 |
delete *captured_stream; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11510 |
*captured_stream = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11511 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11512 |
return content; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11513 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11514 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11515 |
// Starts capturing stdout. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11516 |
void CaptureStdout() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11517 |
CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11518 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11519 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11520 |
// Starts capturing stderr. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11521 |
void CaptureStderr() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11522 |
CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11523 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11524 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11525 |
// Stops capturing stdout and returns the captured string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11526 |
std::string GetCapturedStdout() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11527 |
return GetCapturedStream(&g_captured_stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11528 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11529 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11530 |
// Stops capturing stderr and returns the captured string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11531 |
std::string GetCapturedStderr() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11532 |
return GetCapturedStream(&g_captured_stderr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11533 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11534 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11535 |
#endif // GTEST_HAS_STREAM_REDIRECTION |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11536 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11537 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11538 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11539 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11540 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11541 |
size_t GetFileSize(FILE* file) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11542 |
fseek(file, 0, SEEK_END); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11543 |
return static_cast<size_t>(ftell(file)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11544 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11545 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11546 |
std::string ReadEntireFile(FILE* file) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11547 |
const size_t file_size = GetFileSize(file); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11548 |
char* const buffer = new char[file_size]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11549 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11550 |
size_t bytes_last_read = 0; // # of bytes read in the last fread() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11551 |
size_t bytes_read = 0; // # of bytes read so far |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11552 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11553 |
fseek(file, 0, SEEK_SET); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11554 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11555 |
// Keeps reading the file until we cannot read further or the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11556 |
// pre-determined file size is reached. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11557 |
do { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11558 |
bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11559 |
bytes_read += bytes_last_read; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11560 |
} while (bytes_last_read > 0 && bytes_read < file_size); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11561 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11562 |
const std::string content(buffer, bytes_read); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11563 |
delete[] buffer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11564 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11565 |
return content; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11566 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11567 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11568 |
#if GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11569 |
static const std::vector<std::string>* g_injected_test_argvs = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11570 |
nullptr; // Owned. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11571 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11572 |
std::vector<std::string> GetInjectableArgvs() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11573 |
if (g_injected_test_argvs != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11574 |
return *g_injected_test_argvs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11575 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11576 |
return GetArgvs(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11577 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11578 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11579 |
void SetInjectableArgvs(const std::vector<std::string>* new_argvs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11580 |
if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11581 |
g_injected_test_argvs = new_argvs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11582 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11583 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11584 |
void SetInjectableArgvs(const std::vector<std::string>& new_argvs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11585 |
SetInjectableArgvs( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11586 |
new std::vector<std::string>(new_argvs.begin(), new_argvs.end())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11587 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11588 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11589 |
void ClearInjectableArgvs() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11590 |
delete g_injected_test_argvs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11591 |
g_injected_test_argvs = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11592 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11593 |
#endif // GTEST_HAS_DEATH_TEST |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11594 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11595 |
#if GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11596 |
namespace posix { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11597 |
void Abort() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11598 |
DebugBreak(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11599 |
TerminateProcess(GetCurrentProcess(), 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11600 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11601 |
} // namespace posix |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11602 |
#endif // GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11603 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11604 |
// Returns the name of the environment variable corresponding to the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11605 |
// given flag. For example, FlagToEnvVar("foo") will return |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11606 |
// "GTEST_FOO" in the open-source version. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11607 |
static std::string FlagToEnvVar(const char* flag) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11608 |
const std::string full_flag = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11609 |
(Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11610 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11611 |
Message env_var; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11612 |
for (size_t i = 0; i != full_flag.length(); i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11613 |
env_var << ToUpper(full_flag.c_str()[i]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11614 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11615 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11616 |
return env_var.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11617 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11618 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11619 |
// Parses 'str' for a 32-bit signed integer. If successful, writes |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11620 |
// the result to *value and returns true; otherwise leaves *value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11621 |
// unchanged and returns false. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11622 |
bool ParseInt32(const Message& src_text, const char* str, int32_t* value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11623 |
// Parses the environment variable as a decimal integer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11624 |
char* end = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11625 |
const long long_value = strtol(str, &end, 10); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11626 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11627 |
// Has strtol() consumed all characters in the string? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11628 |
if (*end != '\0') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11629 |
// No - an invalid character was encountered. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11630 |
Message msg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11631 |
msg << "WARNING: " << src_text |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11632 |
<< " is expected to be a 32-bit integer, but actually" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11633 |
<< " has value \"" << str << "\".\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11634 |
printf("%s", msg.GetString().c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11635 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11636 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11637 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11638 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11639 |
// Is the parsed value in the range of an int32_t? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11640 |
const auto result = static_cast<int32_t>(long_value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11641 |
if (long_value == LONG_MAX || long_value == LONG_MIN || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11642 |
// The parsed value overflows as a long. (strtol() returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11643 |
// LONG_MAX or LONG_MIN when the input overflows.) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11644 |
result != long_value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11645 |
// The parsed value overflows as an int32_t. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11646 |
) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11647 |
Message msg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11648 |
msg << "WARNING: " << src_text |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11649 |
<< " is expected to be a 32-bit integer, but actually" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11650 |
<< " has value " << str << ", which overflows.\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11651 |
printf("%s", msg.GetString().c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11652 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11653 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11654 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11655 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11656 |
*value = result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11657 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11658 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11659 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11660 |
// Reads and returns the Boolean environment variable corresponding to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11661 |
// the given flag; if it's not set, returns default_value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11662 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11663 |
// The value is considered true if and only if it's not "0". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11664 |
bool BoolFromGTestEnv(const char* flag, bool default_value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11665 |
#if defined(GTEST_GET_BOOL_FROM_ENV_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11666 |
return GTEST_GET_BOOL_FROM_ENV_(flag, default_value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11667 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11668 |
const std::string env_var = FlagToEnvVar(flag); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11669 |
const char* const string_value = posix::GetEnv(env_var.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11670 |
return string_value == nullptr ? default_value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11671 |
: strcmp(string_value, "0") != 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11672 |
#endif // defined(GTEST_GET_BOOL_FROM_ENV_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11673 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11674 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11675 |
// Reads and returns a 32-bit integer stored in the environment |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11676 |
// variable corresponding to the given flag; if it isn't set or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11677 |
// doesn't represent a valid 32-bit integer, returns default_value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11678 |
int32_t Int32FromGTestEnv(const char* flag, int32_t default_value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11679 |
#if defined(GTEST_GET_INT32_FROM_ENV_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11680 |
return GTEST_GET_INT32_FROM_ENV_(flag, default_value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11681 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11682 |
const std::string env_var = FlagToEnvVar(flag); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11683 |
const char* const string_value = posix::GetEnv(env_var.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11684 |
if (string_value == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11685 |
// The environment variable is not set. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11686 |
return default_value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11687 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11688 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11689 |
int32_t result = default_value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11690 |
if (!ParseInt32(Message() << "Environment variable " << env_var, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11691 |
string_value, &result)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11692 |
printf("The default value %s is used.\n", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11693 |
(Message() << default_value).GetString().c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11694 |
fflush(stdout); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11695 |
return default_value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11696 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11697 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11698 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11699 |
#endif // defined(GTEST_GET_INT32_FROM_ENV_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11700 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11701 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11702 |
// As a special case for the 'output' flag, if GTEST_OUTPUT is not |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11703 |
// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11704 |
// system. The value of XML_OUTPUT_FILE is a filename without the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11705 |
// "xml:" prefix of GTEST_OUTPUT. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11706 |
// Note that this is meant to be called at the call site so it does |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11707 |
// not check that the flag is 'output' |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11708 |
// In essence this checks an env variable called XML_OUTPUT_FILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11709 |
// and if it is set we prepend "xml:" to its value, if it not set we return "" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11710 |
std::string OutputFlagAlsoCheckEnvVar(){ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11711 |
std::string default_value_for_output_flag = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11712 |
const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11713 |
if (nullptr != xml_output_file_env) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11714 |
default_value_for_output_flag = std::string("xml:") + xml_output_file_env; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11715 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11716 |
return default_value_for_output_flag; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11717 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11718 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11719 |
// Reads and returns the string environment variable corresponding to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11720 |
// the given flag; if it's not set, returns default_value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11721 |
const char* StringFromGTestEnv(const char* flag, const char* default_value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11722 |
#if defined(GTEST_GET_STRING_FROM_ENV_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11723 |
return GTEST_GET_STRING_FROM_ENV_(flag, default_value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11724 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11725 |
const std::string env_var = FlagToEnvVar(flag); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11726 |
const char* const value = posix::GetEnv(env_var.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11727 |
return value == nullptr ? default_value : value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11728 |
#endif // defined(GTEST_GET_STRING_FROM_ENV_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11729 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11730 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11731 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11732 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11733 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11734 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11735 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11736 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11737 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11738 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11739 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11740 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11741 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11742 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11743 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11744 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11745 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11746 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11747 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11748 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11749 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11750 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11751 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11752 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11753 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11754 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11755 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11756 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11757 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11758 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11759 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11760 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11761 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11762 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11763 |
// Google Test - The Google C++ Testing and Mocking Framework |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11764 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11765 |
// This file implements a universal value printer that can print a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11766 |
// value of any type T: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11767 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11768 |
// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11769 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11770 |
// It uses the << operator when possible, and prints the bytes in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11771 |
// object otherwise. A user can override its behavior for a class |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11772 |
// type Foo by defining either operator<<(::std::ostream&, const Foo&) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11773 |
// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11774 |
// defines Foo. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11775 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11776 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11777 |
#include <stdio.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11778 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11779 |
#include <cctype> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11780 |
#include <cstdint> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11781 |
#include <cwchar> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11782 |
#include <ostream> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11783 |
#include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11784 |
#include <type_traits> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11785 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11786 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11787 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11788 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11789 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11790 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11791 |
using ::std::ostream; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11792 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11793 |
// Prints a segment of bytes in the given object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11794 |
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11795 |
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11796 |
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11797 |
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11798 |
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11799 |
size_t count, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11800 |
char text[5] = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11801 |
for (size_t i = 0; i != count; i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11802 |
const size_t j = start + i; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11803 |
if (i != 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11804 |
// Organizes the bytes into groups of 2 for easy parsing by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11805 |
// human. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11806 |
if ((j % 2) == 0) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11807 |
*os << ' '; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11808 |
else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11809 |
*os << '-'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11810 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11811 |
GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11812 |
*os << text; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11813 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11814 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11815 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11816 |
// Prints the bytes in the given value to the given ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11817 |
void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11818 |
ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11819 |
// Tells the user how big the object is. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11820 |
*os << count << "-byte object <"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11821 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11822 |
const size_t kThreshold = 132; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11823 |
const size_t kChunkSize = 64; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11824 |
// If the object size is bigger than kThreshold, we'll have to omit |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11825 |
// some details by printing only the first and the last kChunkSize |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11826 |
// bytes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11827 |
if (count < kThreshold) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11828 |
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11829 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11830 |
PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11831 |
*os << " ... "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11832 |
// Rounds up to 2-byte boundary. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11833 |
const size_t resume_pos = (count - kChunkSize + 1)/2*2; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11834 |
PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11835 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11836 |
*os << ">"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11837 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11838 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11839 |
// Helpers for widening a character to char32_t. Since the standard does not |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11840 |
// specify if char / wchar_t is signed or unsigned, it is important to first |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11841 |
// convert it to the unsigned type of the same width before widening it to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11842 |
// char32_t. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11843 |
template <typename CharType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11844 |
char32_t ToChar32(CharType in) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11845 |
return static_cast<char32_t>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11846 |
static_cast<typename std::make_unsigned<CharType>::type>(in)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11847 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11848 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11849 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11850 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11851 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11852 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11853 |
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11854 |
// given object. The delegation simplifies the implementation, which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11855 |
// uses the << operator and thus is easier done outside of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11856 |
// ::testing::internal namespace, which contains a << operator that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11857 |
// sometimes conflicts with the one in STL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11858 |
void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11859 |
ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11860 |
PrintBytesInObjectToImpl(obj_bytes, count, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11861 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11862 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11863 |
// Depending on the value of a char (or wchar_t), we print it in one |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11864 |
// of three formats: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11865 |
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11866 |
// - as a hexadecimal escape sequence (e.g. '\x7F'), or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11867 |
// - as a special escape sequence (e.g. '\r', '\n'). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11868 |
enum CharFormat { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11869 |
kAsIs, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11870 |
kHexEscape, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11871 |
kSpecialEscape |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11872 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11873 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11874 |
// Returns true if c is a printable ASCII character. We test the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11875 |
// value of c directly instead of calling isprint(), which is buggy on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11876 |
// Windows Mobile. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11877 |
inline bool IsPrintableAscii(char32_t c) { return 0x20 <= c && c <= 0x7E; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11878 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11879 |
// Prints c (of type char, char8_t, char16_t, char32_t, or wchar_t) as a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11880 |
// character literal without the quotes, escaping it when necessary; returns how |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11881 |
// c was formatted. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11882 |
template <typename Char> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11883 |
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11884 |
const char32_t u_c = ToChar32(c); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11885 |
switch (u_c) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11886 |
case L'\0': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11887 |
*os << "\\0"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11888 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11889 |
case L'\'': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11890 |
*os << "\\'"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11891 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11892 |
case L'\\': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11893 |
*os << "\\\\"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11894 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11895 |
case L'\a': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11896 |
*os << "\\a"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11897 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11898 |
case L'\b': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11899 |
*os << "\\b"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11900 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11901 |
case L'\f': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11902 |
*os << "\\f"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11903 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11904 |
case L'\n': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11905 |
*os << "\\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11906 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11907 |
case L'\r': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11908 |
*os << "\\r"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11909 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11910 |
case L'\t': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11911 |
*os << "\\t"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11912 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11913 |
case L'\v': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11914 |
*os << "\\v"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11915 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11916 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11917 |
if (IsPrintableAscii(u_c)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11918 |
*os << static_cast<char>(c); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11919 |
return kAsIs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11920 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11921 |
ostream::fmtflags flags = os->flags(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11922 |
*os << "\\x" << std::hex << std::uppercase << static_cast<int>(u_c); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11923 |
os->flags(flags); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11924 |
return kHexEscape; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11925 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11926 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11927 |
return kSpecialEscape; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11928 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11929 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11930 |
// Prints a char32_t c as if it's part of a string literal, escaping it when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11931 |
// necessary; returns how c was formatted. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11932 |
static CharFormat PrintAsStringLiteralTo(char32_t c, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11933 |
switch (c) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11934 |
case L'\'': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11935 |
*os << "'"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11936 |
return kAsIs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11937 |
case L'"': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11938 |
*os << "\\\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11939 |
return kSpecialEscape; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11940 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11941 |
return PrintAsCharLiteralTo(c, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11942 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11943 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11944 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11945 |
static const char* GetCharWidthPrefix(char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11946 |
return ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11947 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11948 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11949 |
static const char* GetCharWidthPrefix(signed char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11950 |
return ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11951 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11952 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11953 |
static const char* GetCharWidthPrefix(unsigned char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11954 |
return ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11955 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11956 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11957 |
#ifdef __cpp_char8_t |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11958 |
static const char* GetCharWidthPrefix(char8_t) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11959 |
return "u8"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11960 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11961 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11962 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11963 |
static const char* GetCharWidthPrefix(char16_t) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11964 |
return "u"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11965 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11966 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11967 |
static const char* GetCharWidthPrefix(char32_t) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11968 |
return "U"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11969 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11970 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11971 |
static const char* GetCharWidthPrefix(wchar_t) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11972 |
return "L"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11973 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11974 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11975 |
// Prints a char c as if it's part of a string literal, escaping it when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11976 |
// necessary; returns how c was formatted. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11977 |
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11978 |
return PrintAsStringLiteralTo(ToChar32(c), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11979 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11980 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11981 |
#ifdef __cpp_char8_t |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11982 |
static CharFormat PrintAsStringLiteralTo(char8_t c, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11983 |
return PrintAsStringLiteralTo(ToChar32(c), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11984 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11985 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11986 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11987 |
static CharFormat PrintAsStringLiteralTo(char16_t c, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11988 |
return PrintAsStringLiteralTo(ToChar32(c), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11989 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11990 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11991 |
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11992 |
return PrintAsStringLiteralTo(ToChar32(c), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11993 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11994 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11995 |
// Prints a character c (of type char, char8_t, char16_t, char32_t, or wchar_t) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11996 |
// and its code. '\0' is printed as "'\\0'", other unprintable characters are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11997 |
// also properly escaped using the standard C++ escape sequence. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11998 |
template <typename Char> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11999 |
void PrintCharAndCodeTo(Char c, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12000 |
// First, print c as a literal in the most readable form we can find. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12001 |
*os << GetCharWidthPrefix(c) << "'"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12002 |
const CharFormat format = PrintAsCharLiteralTo(c, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12003 |
*os << "'"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12004 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12005 |
// To aid user debugging, we also print c's code in decimal, unless |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12006 |
// it's 0 (in which case c was printed as '\\0', making the code |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12007 |
// obvious). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12008 |
if (c == 0) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12009 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12010 |
*os << " (" << static_cast<int>(c); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12011 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12012 |
// For more convenience, we print c's code again in hexadecimal, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12013 |
// unless c was already printed in the form '\x##' or the code is in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12014 |
// [1, 9]. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12015 |
if (format == kHexEscape || (1 <= c && c <= 9)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12016 |
// Do nothing. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12017 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12018 |
*os << ", 0x" << String::FormatHexInt(static_cast<int>(c)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12019 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12020 |
*os << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12021 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12022 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12023 |
void PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12024 |
void PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12025 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12026 |
// Prints a wchar_t as a symbol if it is printable or as its internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12027 |
// code otherwise and also as its code. L'\0' is printed as "L'\\0'". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12028 |
void PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12029 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12030 |
// TODO(dcheng): Consider making this delegate to PrintCharAndCodeTo() as well. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12031 |
void PrintTo(char32_t c, ::std::ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12032 |
*os << std::hex << "U+" << std::uppercase << std::setfill('0') << std::setw(4) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12033 |
<< static_cast<uint32_t>(c); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12034 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12035 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12036 |
// Prints the given array of characters to the ostream. CharType must be either |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12037 |
// char, char8_t, char16_t, char32_t, or wchar_t. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12038 |
// The array starts at begin, the length is len, it may include '\0' characters |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12039 |
// and may not be NUL-terminated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12040 |
template <typename CharType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12041 |
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12042 |
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12043 |
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12044 |
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12045 |
static CharFormat PrintCharsAsStringTo( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12046 |
const CharType* begin, size_t len, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12047 |
const char* const quote_prefix = GetCharWidthPrefix(*begin); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12048 |
*os << quote_prefix << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12049 |
bool is_previous_hex = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12050 |
CharFormat print_format = kAsIs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12051 |
for (size_t index = 0; index < len; ++index) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12052 |
const CharType cur = begin[index]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12053 |
if (is_previous_hex && IsXDigit(cur)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12054 |
// Previous character is of '\x..' form and this character can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12055 |
// interpreted as another hexadecimal digit in its number. Break string to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12056 |
// disambiguate. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12057 |
*os << "\" " << quote_prefix << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12058 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12059 |
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12060 |
// Remember if any characters required hex escaping. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12061 |
if (is_previous_hex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12062 |
print_format = kHexEscape; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12063 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12064 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12065 |
*os << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12066 |
return print_format; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12067 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12068 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12069 |
// Prints a (const) char/wchar_t array of 'len' elements, starting at address |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12070 |
// 'begin'. CharType must be either char or wchar_t. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12071 |
template <typename CharType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12072 |
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12073 |
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12074 |
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12075 |
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12076 |
static void UniversalPrintCharArray( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12077 |
const CharType* begin, size_t len, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12078 |
// The code |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12079 |
// const char kFoo[] = "foo"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12080 |
// generates an array of 4, not 3, elements, with the last one being '\0'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12081 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12082 |
// Therefore when printing a char array, we don't print the last element if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12083 |
// it's '\0', such that the output matches the string literal as it's |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12084 |
// written in the source code. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12085 |
if (len > 0 && begin[len - 1] == '\0') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12086 |
PrintCharsAsStringTo(begin, len - 1, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12087 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12088 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12089 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12090 |
// If, however, the last element in the array is not '\0', e.g. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12091 |
// const char kFoo[] = { 'f', 'o', 'o' }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12092 |
// we must print the entire array. We also print a message to indicate |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12093 |
// that the array is not NUL-terminated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12094 |
PrintCharsAsStringTo(begin, len, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12095 |
*os << " (no terminating NUL)"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12096 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12097 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12098 |
// Prints a (const) char array of 'len' elements, starting at address 'begin'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12099 |
void UniversalPrintArray(const char* begin, size_t len, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12100 |
UniversalPrintCharArray(begin, len, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12101 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12102 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12103 |
#ifdef __cpp_char8_t |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12104 |
// Prints a (const) char8_t array of 'len' elements, starting at address |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12105 |
// 'begin'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12106 |
void UniversalPrintArray(const char8_t* begin, size_t len, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12107 |
UniversalPrintCharArray(begin, len, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12108 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12109 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12110 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12111 |
// Prints a (const) char16_t array of 'len' elements, starting at address |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12112 |
// 'begin'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12113 |
void UniversalPrintArray(const char16_t* begin, size_t len, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12114 |
UniversalPrintCharArray(begin, len, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12115 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12116 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12117 |
// Prints a (const) char32_t array of 'len' elements, starting at address |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12118 |
// 'begin'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12119 |
void UniversalPrintArray(const char32_t* begin, size_t len, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12120 |
UniversalPrintCharArray(begin, len, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12121 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12122 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12123 |
// Prints a (const) wchar_t array of 'len' elements, starting at address |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12124 |
// 'begin'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12125 |
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12126 |
UniversalPrintCharArray(begin, len, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12127 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12128 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12129 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12130 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12131 |
// Prints a null-terminated C-style string to the ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12132 |
template <typename Char> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12133 |
void PrintCStringTo(const Char* s, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12134 |
if (s == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12135 |
*os << "NULL"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12136 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12137 |
*os << ImplicitCast_<const void*>(s) << " pointing to "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12138 |
PrintCharsAsStringTo(s, std::char_traits<Char>::length(s), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12139 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12140 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12141 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12142 |
} // anonymous namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12143 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12144 |
void PrintTo(const char* s, ostream* os) { PrintCStringTo(s, os); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12145 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12146 |
#ifdef __cpp_char8_t |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12147 |
void PrintTo(const char8_t* s, ostream* os) { PrintCStringTo(s, os); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12148 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12149 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12150 |
void PrintTo(const char16_t* s, ostream* os) { PrintCStringTo(s, os); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12151 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12152 |
void PrintTo(const char32_t* s, ostream* os) { PrintCStringTo(s, os); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12153 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12154 |
// MSVC compiler can be configured to define whar_t as a typedef |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12155 |
// of unsigned short. Defining an overload for const wchar_t* in that case |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12156 |
// would cause pointers to unsigned shorts be printed as wide strings, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12157 |
// possibly accessing more memory than intended and causing invalid |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12158 |
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12159 |
// wchar_t is implemented as a native type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12160 |
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12161 |
// Prints the given wide C string to the ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12162 |
void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12163 |
#endif // wchar_t is native |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12164 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12165 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12166 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12167 |
bool ContainsUnprintableControlCodes(const char* str, size_t length) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12168 |
const unsigned char *s = reinterpret_cast<const unsigned char *>(str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12169 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12170 |
for (size_t i = 0; i < length; i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12171 |
unsigned char ch = *s++; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12172 |
if (std::iscntrl(ch)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12173 |
switch (ch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12174 |
case '\t': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12175 |
case '\n': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12176 |
case '\r': |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12177 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12178 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12179 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12180 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12181 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12182 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12183 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12184 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12185 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12186 |
bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t<= 0xbf; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12187 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12188 |
bool IsValidUTF8(const char* str, size_t length) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12189 |
const unsigned char *s = reinterpret_cast<const unsigned char *>(str); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12190 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12191 |
for (size_t i = 0; i < length;) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12192 |
unsigned char lead = s[i++]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12193 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12194 |
if (lead <= 0x7f) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12195 |
continue; // single-byte character (ASCII) 0..7F |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12196 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12197 |
if (lead < 0xc2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12198 |
return false; // trail byte or non-shortest form |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12199 |
} else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12200 |
++i; // 2-byte character |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12201 |
} else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12202 |
IsUTF8TrailByte(s[i]) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12203 |
IsUTF8TrailByte(s[i + 1]) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12204 |
// check for non-shortest form and surrogate |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12205 |
(lead != 0xe0 || s[i] >= 0xa0) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12206 |
(lead != 0xed || s[i] < 0xa0)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12207 |
i += 2; // 3-byte character |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12208 |
} else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12209 |
IsUTF8TrailByte(s[i]) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12210 |
IsUTF8TrailByte(s[i + 1]) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12211 |
IsUTF8TrailByte(s[i + 2]) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12212 |
// check for non-shortest form |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12213 |
(lead != 0xf0 || s[i] >= 0x90) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12214 |
(lead != 0xf4 || s[i] < 0x90)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12215 |
i += 3; // 4-byte character |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12216 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12217 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12218 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12219 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12220 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12221 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12222 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12223 |
void ConditionalPrintAsText(const char* str, size_t length, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12224 |
if (!ContainsUnprintableControlCodes(str, length) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12225 |
IsValidUTF8(str, length)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12226 |
*os << "\n As Text: \"" << str << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12227 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12228 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12229 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12230 |
} // anonymous namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12231 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12232 |
void PrintStringTo(const ::std::string& s, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12233 |
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12234 |
if (GTEST_FLAG(print_utf8)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12235 |
ConditionalPrintAsText(s.data(), s.size(), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12236 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12237 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12238 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12239 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12240 |
#ifdef __cpp_char8_t |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12241 |
void PrintU8StringTo(const ::std::u8string& s, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12242 |
PrintCharsAsStringTo(s.data(), s.size(), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12243 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12244 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12245 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12246 |
void PrintU16StringTo(const ::std::u16string& s, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12247 |
PrintCharsAsStringTo(s.data(), s.size(), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12248 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12249 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12250 |
void PrintU32StringTo(const ::std::u32string& s, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12251 |
PrintCharsAsStringTo(s.data(), s.size(), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12252 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12253 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12254 |
#if GTEST_HAS_STD_WSTRING |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12255 |
void PrintWideStringTo(const ::std::wstring& s, ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12256 |
PrintCharsAsStringTo(s.data(), s.size(), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12257 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12258 |
#endif // GTEST_HAS_STD_WSTRING |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12259 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12260 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12261 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12262 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12263 |
// Copyright 2008, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12264 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12265 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12266 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12267 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12268 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12269 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12270 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12271 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12272 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12273 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12274 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12275 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12276 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12277 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12278 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12279 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12280 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12281 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12282 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12283 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12284 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12285 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12286 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12287 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12288 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12289 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12290 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12291 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12292 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12293 |
// The Google C++ Testing and Mocking Framework (Google Test) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12294 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12295 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12296 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12297 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12298 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12299 |
using internal::GetUnitTestImpl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12300 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12301 |
// Gets the summary of the failure message by omitting the stack trace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12302 |
// in it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12303 |
std::string TestPartResult::ExtractSummary(const char* message) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12304 |
const char* const stack_trace = strstr(message, internal::kStackTraceMarker); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12305 |
return stack_trace == nullptr ? message : std::string(message, stack_trace); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12306 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12307 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12308 |
// Prints a TestPartResult object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12309 |
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12310 |
return os << internal::FormatFileLocation(result.file_name(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12311 |
result.line_number()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12312 |
<< " " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12313 |
<< (result.type() == TestPartResult::kSuccess |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12314 |
? "Success" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12315 |
: result.type() == TestPartResult::kSkip |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12316 |
? "Skipped" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12317 |
: result.type() == TestPartResult::kFatalFailure |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12318 |
? "Fatal failure" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12319 |
: "Non-fatal failure") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12320 |
<< ":\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12321 |
<< result.message() << std::endl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12322 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12323 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12324 |
// Appends a TestPartResult to the array. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12325 |
void TestPartResultArray::Append(const TestPartResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12326 |
array_.push_back(result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12327 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12328 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12329 |
// Returns the TestPartResult at the given index (0-based). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12330 |
const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12331 |
if (index < 0 || index >= size()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12332 |
printf("\nInvalid index (%d) into TestPartResultArray.\n", index); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12333 |
internal::posix::Abort(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12334 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12335 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12336 |
return array_[static_cast<size_t>(index)]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12337 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12338 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12339 |
// Returns the number of TestPartResult objects in the array. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12340 |
int TestPartResultArray::size() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12341 |
return static_cast<int>(array_.size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12342 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12343 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12344 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12345 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12346 |
HasNewFatalFailureHelper::HasNewFatalFailureHelper() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12347 |
: has_new_fatal_failure_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12348 |
original_reporter_(GetUnitTestImpl()-> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12349 |
GetTestPartResultReporterForCurrentThread()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12350 |
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12351 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12352 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12353 |
HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12354 |
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12355 |
original_reporter_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12356 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12357 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12358 |
void HasNewFatalFailureHelper::ReportTestPartResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12359 |
const TestPartResult& result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12360 |
if (result.fatally_failed()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12361 |
has_new_fatal_failure_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12362 |
original_reporter_->ReportTestPartResult(result); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12363 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12364 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12365 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12366 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12367 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12368 |
// Copyright 2008 Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12369 |
// All Rights Reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12370 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12371 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12372 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12373 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12374 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12375 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12376 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12377 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12378 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12379 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12380 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12381 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12382 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12383 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12384 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12385 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12386 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12387 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12388 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12389 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12390 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12391 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12392 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12393 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12394 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12395 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12396 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12397 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12398 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12399 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12400 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12401 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12402 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12403 |
// Skips to the first non-space char in str. Returns an empty string if str |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12404 |
// contains only whitespace characters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12405 |
static const char* SkipSpaces(const char* str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12406 |
while (IsSpace(*str)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12407 |
str++; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12408 |
return str; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12409 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12410 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12411 |
static std::vector<std::string> SplitIntoTestNames(const char* src) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12412 |
std::vector<std::string> name_vec; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12413 |
src = SkipSpaces(src); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12414 |
for (; src != nullptr; src = SkipComma(src)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12415 |
name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12416 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12417 |
return name_vec; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12418 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12419 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12420 |
// Verifies that registered_tests match the test names in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12421 |
// registered_tests_; returns registered_tests if successful, or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12422 |
// aborts the program otherwise. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12423 |
const char* TypedTestSuitePState::VerifyRegisteredTestNames( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12424 |
const char* test_suite_name, const char* file, int line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12425 |
const char* registered_tests) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12426 |
RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12427 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12428 |
typedef RegisteredTestsMap::const_iterator RegisteredTestIter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12429 |
registered_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12430 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12431 |
std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12432 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12433 |
Message errors; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12434 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12435 |
std::set<std::string> tests; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12436 |
for (std::vector<std::string>::const_iterator name_it = name_vec.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12437 |
name_it != name_vec.end(); ++name_it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12438 |
const std::string& name = *name_it; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12439 |
if (tests.count(name) != 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12440 |
errors << "Test " << name << " is listed more than once.\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12441 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12442 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12443 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12444 |
if (registered_tests_.count(name) != 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12445 |
tests.insert(name); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12446 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12447 |
errors << "No test named " << name |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12448 |
<< " can be found in this test suite.\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12449 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12450 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12451 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12452 |
for (RegisteredTestIter it = registered_tests_.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12453 |
it != registered_tests_.end(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12454 |
++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12455 |
if (tests.count(it->first) == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12456 |
errors << "You forgot to list test " << it->first << ".\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12457 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12458 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12459 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12460 |
const std::string& errors_str = errors.GetString(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12461 |
if (errors_str != "") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12462 |
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12463 |
errors_str.c_str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12464 |
fflush(stderr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12465 |
posix::Abort(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12466 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12467 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12468 |
return registered_tests; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12469 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12470 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12471 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12472 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12473 |
// Copyright 2008, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12474 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12475 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12476 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12477 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12478 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12479 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12480 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12481 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12482 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12483 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12484 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12485 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12486 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12487 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12488 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12489 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12490 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12491 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12492 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12493 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12494 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12495 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12496 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12497 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12498 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12499 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12500 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12501 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12502 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12503 |
// Google C++ Mocking Framework (Google Mock) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12504 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12505 |
// This file #includes all Google Mock implementation .cc files. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12506 |
// purpose is to allow a user to build Google Mock by compiling this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12507 |
// file alone. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12508 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12509 |
// This line ensures that gmock.h can be compiled on its own, even |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12510 |
// when it's fused. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12511 |
#include "gmock/gmock.h" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12512 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12513 |
// The following lines pull in the real gmock *.cc files. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12514 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12515 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12516 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12517 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12518 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12519 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12520 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12521 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12522 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12523 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12524 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12525 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12526 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12527 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12528 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12529 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12530 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12531 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12532 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12533 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12534 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12535 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12536 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12537 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12538 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12539 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12540 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12541 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12542 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12543 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12544 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12545 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12546 |
// This file implements cardinalities. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12547 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12548 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12549 |
#include <limits.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12550 |
#include <ostream> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12551 |
#include <sstream> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12552 |
#include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12553 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12554 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12555 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12556 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12557 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12558 |
// Implements the Between(m, n) cardinality. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12559 |
class BetweenCardinalityImpl : public CardinalityInterface { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12560 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12561 |
BetweenCardinalityImpl(int min, int max) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12562 |
: min_(min >= 0 ? min : 0), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12563 |
max_(max >= min_ ? max : min_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12564 |
std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12565 |
if (min < 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12566 |
ss << "The invocation lower bound must be >= 0, " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12567 |
<< "but is actually " << min << "."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12568 |
internal::Expect(false, __FILE__, __LINE__, ss.str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12569 |
} else if (max < 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12570 |
ss << "The invocation upper bound must be >= 0, " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12571 |
<< "but is actually " << max << "."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12572 |
internal::Expect(false, __FILE__, __LINE__, ss.str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12573 |
} else if (min > max) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12574 |
ss << "The invocation upper bound (" << max |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12575 |
<< ") must be >= the invocation lower bound (" << min |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12576 |
<< ")."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12577 |
internal::Expect(false, __FILE__, __LINE__, ss.str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12578 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12579 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12580 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12581 |
// Conservative estimate on the lower/upper bound of the number of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12582 |
// calls allowed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12583 |
int ConservativeLowerBound() const override { return min_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12584 |
int ConservativeUpperBound() const override { return max_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12585 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12586 |
bool IsSatisfiedByCallCount(int call_count) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12587 |
return min_ <= call_count && call_count <= max_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12588 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12589 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12590 |
bool IsSaturatedByCallCount(int call_count) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12591 |
return call_count >= max_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12592 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12593 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12594 |
void DescribeTo(::std::ostream* os) const override; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12595 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12596 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12597 |
const int min_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12598 |
const int max_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12599 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12600 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12601 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12602 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12603 |
// Formats "n times" in a human-friendly way. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12604 |
inline std::string FormatTimes(int n) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12605 |
if (n == 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12606 |
return "once"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12607 |
} else if (n == 2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12608 |
return "twice"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12609 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12610 |
std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12611 |
ss << n << " times"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12612 |
return ss.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12613 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12614 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12615 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12616 |
// Describes the Between(m, n) cardinality in human-friendly text. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12617 |
void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12618 |
if (min_ == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12619 |
if (max_ == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12620 |
*os << "never called"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12621 |
} else if (max_ == INT_MAX) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12622 |
*os << "called any number of times"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12623 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12624 |
*os << "called at most " << FormatTimes(max_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12625 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12626 |
} else if (min_ == max_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12627 |
*os << "called " << FormatTimes(min_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12628 |
} else if (max_ == INT_MAX) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12629 |
*os << "called at least " << FormatTimes(min_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12630 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12631 |
// 0 < min_ < max_ < INT_MAX |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12632 |
*os << "called between " << min_ << " and " << max_ << " times"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12633 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12634 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12635 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12636 |
} // Unnamed namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12637 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12638 |
// Describes the given call count to an ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12639 |
void Cardinality::DescribeActualCallCountTo(int actual_call_count, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12640 |
::std::ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12641 |
if (actual_call_count > 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12642 |
*os << "called " << FormatTimes(actual_call_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12643 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12644 |
*os << "never called"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12645 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12646 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12647 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12648 |
// Creates a cardinality that allows at least n calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12649 |
GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12650 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12651 |
// Creates a cardinality that allows at most n calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12652 |
GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12653 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12654 |
// Creates a cardinality that allows any number of calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12655 |
GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12656 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12657 |
// Creates a cardinality that allows between min and max calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12658 |
GTEST_API_ Cardinality Between(int min, int max) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12659 |
return Cardinality(new BetweenCardinalityImpl(min, max)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12660 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12661 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12662 |
// Creates a cardinality that allows exactly n calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12663 |
GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12664 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12665 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12666 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12667 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12668 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12669 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12670 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12671 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12672 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12673 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12674 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12675 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12676 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12677 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12678 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12679 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12680 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12681 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12682 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12683 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12684 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12685 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12686 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12687 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12688 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12689 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12690 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12691 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12692 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12693 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12694 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12695 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12696 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12697 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12698 |
// This file defines some utilities useful for implementing Google |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12699 |
// Mock. They are subject to change without notice, so please DO NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12700 |
// USE THEM IN USER CODE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12701 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12702 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12703 |
#include <ctype.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12704 |
#include <ostream> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12705 |
#include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12706 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12707 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12708 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12709 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12710 |
// Joins a vector of strings as if they are fields of a tuple; returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12711 |
// the joined string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12712 |
GTEST_API_ std::string JoinAsTuple(const Strings& fields) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12713 |
switch (fields.size()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12714 |
case 0: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12715 |
return ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12716 |
case 1: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12717 |
return fields[0]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12718 |
default: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12719 |
std::string result = "(" + fields[0]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12720 |
for (size_t i = 1; i < fields.size(); i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12721 |
result += ", "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12722 |
result += fields[i]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12723 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12724 |
result += ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12725 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12726 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12727 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12728 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12729 |
// Converts an identifier name to a space-separated list of lower-case |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12730 |
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12731 |
// treated as one word. For example, both "FooBar123" and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12732 |
// "foo_bar_123" are converted to "foo bar 123". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12733 |
GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12734 |
std::string result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12735 |
char prev_char = '\0'; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12736 |
for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12737 |
// We don't care about the current locale as the input is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12738 |
// guaranteed to be a valid C++ identifier name. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12739 |
const bool starts_new_word = IsUpper(*p) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12740 |
(!IsAlpha(prev_char) && IsLower(*p)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12741 |
(!IsDigit(prev_char) && IsDigit(*p)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12742 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12743 |
if (IsAlNum(*p)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12744 |
if (starts_new_word && result != "") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12745 |
result += ' '; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12746 |
result += ToLower(*p); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12747 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12748 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12749 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12750 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12751 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12752 |
// This class reports Google Mock failures as Google Test failures. A |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12753 |
// user can define another class in a similar fashion if they intend to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12754 |
// use Google Mock with a testing framework other than Google Test. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12755 |
class GoogleTestFailureReporter : public FailureReporterInterface { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12756 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12757 |
void ReportFailure(FailureType type, const char* file, int line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12758 |
const std::string& message) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12759 |
AssertHelper(type == kFatal ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12760 |
TestPartResult::kFatalFailure : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12761 |
TestPartResult::kNonFatalFailure, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12762 |
file, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12763 |
line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12764 |
message.c_str()) = Message(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12765 |
if (type == kFatal) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12766 |
posix::Abort(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12767 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12768 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12769 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12770 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12771 |
// Returns the global failure reporter. Will create a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12772 |
// GoogleTestFailureReporter and return it the first time called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12773 |
GTEST_API_ FailureReporterInterface* GetFailureReporter() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12774 |
// Points to the global failure reporter used by Google Mock. gcc |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12775 |
// guarantees that the following use of failure_reporter is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12776 |
// thread-safe. We may need to add additional synchronization to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12777 |
// protect failure_reporter if we port Google Mock to other |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12778 |
// compilers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12779 |
static FailureReporterInterface* const failure_reporter = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12780 |
new GoogleTestFailureReporter(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12781 |
return failure_reporter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12782 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12783 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12784 |
// Protects global resources (stdout in particular) used by Log(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12785 |
static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12786 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12787 |
// Returns true if and only if a log with the given severity is visible |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12788 |
// according to the --gmock_verbose flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12789 |
GTEST_API_ bool LogIsVisible(LogSeverity severity) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12790 |
if (GMOCK_FLAG(verbose) == kInfoVerbosity) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12791 |
// Always show the log if --gmock_verbose=info. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12792 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12793 |
} else if (GMOCK_FLAG(verbose) == kErrorVerbosity) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12794 |
// Always hide it if --gmock_verbose=error. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12795 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12796 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12797 |
// If --gmock_verbose is neither "info" nor "error", we treat it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12798 |
// as "warning" (its default value). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12799 |
return severity == kWarning; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12800 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12801 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12802 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12803 |
// Prints the given message to stdout if and only if 'severity' >= the level |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12804 |
// specified by the --gmock_verbose flag. If stack_frames_to_skip >= |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12805 |
// 0, also prints the stack trace excluding the top |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12806 |
// stack_frames_to_skip frames. In opt mode, any positive |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12807 |
// stack_frames_to_skip is treated as 0, since we don't know which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12808 |
// function calls will be inlined by the compiler and need to be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12809 |
// conservative. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12810 |
GTEST_API_ void Log(LogSeverity severity, const std::string& message, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12811 |
int stack_frames_to_skip) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12812 |
if (!LogIsVisible(severity)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12813 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12814 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12815 |
// Ensures that logs from different threads don't interleave. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12816 |
MutexLock l(&g_log_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12817 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12818 |
if (severity == kWarning) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12819 |
// Prints a GMOCK WARNING marker to make the warnings easily searchable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12820 |
std::cout << "\nGMOCK WARNING:"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12821 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12822 |
// Pre-pends a new-line to message if it doesn't start with one. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12823 |
if (message.empty() || message[0] != '\n') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12824 |
std::cout << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12825 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12826 |
std::cout << message; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12827 |
if (stack_frames_to_skip >= 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12828 |
#ifdef NDEBUG |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12829 |
// In opt mode, we have to be conservative and skip no stack frame. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12830 |
const int actual_to_skip = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12831 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12832 |
// In dbg mode, we can do what the caller tell us to do (plus one |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12833 |
// for skipping this function's stack frame). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12834 |
const int actual_to_skip = stack_frames_to_skip + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12835 |
#endif // NDEBUG |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12836 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12837 |
// Appends a new-line to message if it doesn't end with one. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12838 |
if (!message.empty() && *message.rbegin() != '\n') { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12839 |
std::cout << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12840 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12841 |
std::cout << "Stack trace:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12842 |
<< ::testing::internal::GetCurrentOsStackTraceExceptTop( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12843 |
::testing::UnitTest::GetInstance(), actual_to_skip); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12844 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12845 |
std::cout << ::std::flush; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12846 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12847 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12848 |
GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12849 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12850 |
GTEST_API_ void IllegalDoDefault(const char* file, int line) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12851 |
internal::Assert( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12852 |
false, file, line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12853 |
"You are using DoDefault() inside a composite action like " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12854 |
"DoAll() or WithArgs(). This is not supported for technical " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12855 |
"reasons. Please instead spell out the default action, or " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12856 |
"assign the default action to an Action variable and use " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12857 |
"the variable in various places."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12858 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12859 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12860 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12861 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12862 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12863 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12864 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12865 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12866 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12867 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12868 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12869 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12870 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12871 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12872 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12873 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12874 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12875 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12876 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12877 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12878 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12879 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12880 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12881 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12882 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12883 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12884 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12885 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12886 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12887 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12888 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12889 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12890 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12891 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12892 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12893 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12894 |
// This file implements Matcher<const string&>, Matcher<string>, and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12895 |
// utilities for defining matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12896 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12897 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12898 |
#include <string.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12899 |
#include <iostream> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12900 |
#include <sstream> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12901 |
#include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12902 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12903 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12904 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12905 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12906 |
// Returns the description for a matcher defined using the MATCHER*() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12907 |
// macro where the user-supplied description string is "", if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12908 |
// 'negation' is false; otherwise returns the description of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12909 |
// negation of the matcher. 'param_values' contains a list of strings |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12910 |
// that are the print-out of the matcher's parameters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12911 |
GTEST_API_ std::string FormatMatcherDescription(bool negation, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12912 |
const char* matcher_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12913 |
const Strings& param_values) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12914 |
std::string result = ConvertIdentifierNameToWords(matcher_name); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12915 |
if (param_values.size() >= 1) result += " " + JoinAsTuple(param_values); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12916 |
return negation ? "not (" + result + ")" : result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12917 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12918 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12919 |
// FindMaxBipartiteMatching and its helper class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12920 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12921 |
// Uses the well-known Ford-Fulkerson max flow method to find a maximum |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12922 |
// bipartite matching. Flow is considered to be from left to right. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12923 |
// There is an implicit source node that is connected to all of the left |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12924 |
// nodes, and an implicit sink node that is connected to all of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12925 |
// right nodes. All edges have unit capacity. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12926 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12927 |
// Neither the flow graph nor the residual flow graph are represented |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12928 |
// explicitly. Instead, they are implied by the information in 'graph' and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12929 |
// a vector<int> called 'left_' whose elements are initialized to the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12930 |
// value kUnused. This represents the initial state of the algorithm, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12931 |
// where the flow graph is empty, and the residual flow graph has the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12932 |
// following edges: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12933 |
// - An edge from source to each left_ node |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12934 |
// - An edge from each right_ node to sink |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12935 |
// - An edge from each left_ node to each right_ node, if the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12936 |
// corresponding edge exists in 'graph'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12937 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12938 |
// When the TryAugment() method adds a flow, it sets left_[l] = r for some |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12939 |
// nodes l and r. This induces the following changes: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12940 |
// - The edges (source, l), (l, r), and (r, sink) are added to the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12941 |
// flow graph. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12942 |
// - The same three edges are removed from the residual flow graph. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12943 |
// - The reverse edges (l, source), (r, l), and (sink, r) are added |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12944 |
// to the residual flow graph, which is a directional graph |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12945 |
// representing unused flow capacity. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12946 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12947 |
// When the method augments a flow (moving left_[l] from some r1 to some |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12948 |
// other r2), this can be thought of as "undoing" the above steps with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12949 |
// respect to r1 and "redoing" them with respect to r2. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12950 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12951 |
// It bears repeating that the flow graph and residual flow graph are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12952 |
// never represented explicitly, but can be derived by looking at the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12953 |
// information in 'graph' and in left_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12954 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12955 |
// As an optimization, there is a second vector<int> called right_ which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12956 |
// does not provide any new information. Instead, it enables more |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12957 |
// efficient queries about edges entering or leaving the right-side nodes |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12958 |
// of the flow or residual flow graphs. The following invariants are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12959 |
// maintained: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12960 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12961 |
// left[l] == kUnused or right[left[l]] == l |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12962 |
// right[r] == kUnused or left[right[r]] == r |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12963 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12964 |
// . [ source ] . |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12965 |
// . ||| . |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12966 |
// . ||| . |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12967 |
// . ||\--> left[0]=1 ---\ right[0]=-1 ----\ . |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12968 |
// . || | | . |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12969 |
// . |\---> left[1]=-1 \--> right[1]=0 ---\| . |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12970 |
// . | || . |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12971 |
// . \----> left[2]=2 ------> right[2]=2 --\|| . |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12972 |
// . ||| . |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12973 |
// . elements matchers vvv . |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12974 |
// . [ sink ] . |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12975 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12976 |
// See Also: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12977 |
// [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12978 |
// "Introduction to Algorithms (Second ed.)", pp. 651-664. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12979 |
// [2] "Ford-Fulkerson algorithm", Wikipedia, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12980 |
// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm' |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12981 |
class MaxBipartiteMatchState { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12982 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12983 |
explicit MaxBipartiteMatchState(const MatchMatrix& graph) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12984 |
: graph_(&graph), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12985 |
left_(graph_->LhsSize(), kUnused), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12986 |
right_(graph_->RhsSize(), kUnused) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12987 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12988 |
// Returns the edges of a maximal match, each in the form {left, right}. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12989 |
ElementMatcherPairs Compute() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12990 |
// 'seen' is used for path finding { 0: unseen, 1: seen }. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12991 |
::std::vector<char> seen; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12992 |
// Searches the residual flow graph for a path from each left node to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12993 |
// the sink in the residual flow graph, and if one is found, add flow |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12994 |
// to the graph. It's okay to search through the left nodes once. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12995 |
// edge from the implicit source node to each previously-visited left |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12996 |
// node will have flow if that left node has any path to the sink |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12997 |
// whatsoever. Subsequent augmentations can only add flow to the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12998 |
// network, and cannot take away that previous flow unit from the source. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12999 |
// Since the source-to-left edge can only carry one flow unit (or, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13000 |
// each element can be matched to only one matcher), there is no need |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13001 |
// to visit the left nodes more than once looking for augmented paths. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13002 |
// The flow is known to be possible or impossible by looking at the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13003 |
// node once. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13004 |
for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13005 |
// Reset the path-marking vector and try to find a path from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13006 |
// source to sink starting at the left_[ilhs] node. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13007 |
GTEST_CHECK_(left_[ilhs] == kUnused) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13008 |
<< "ilhs: " << ilhs << ", left_[ilhs]: " << left_[ilhs]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13009 |
// 'seen' initialized to 'graph_->RhsSize()' copies of 0. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13010 |
seen.assign(graph_->RhsSize(), 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13011 |
TryAugment(ilhs, &seen); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13012 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13013 |
ElementMatcherPairs result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13014 |
for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13015 |
size_t irhs = left_[ilhs]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13016 |
if (irhs == kUnused) continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13017 |
result.push_back(ElementMatcherPair(ilhs, irhs)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13018 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13019 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13020 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13021 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13022 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13023 |
static const size_t kUnused = static_cast<size_t>(-1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13024 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13025 |
// Perform a depth-first search from left node ilhs to the sink. If a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13026 |
// path is found, flow is added to the network by linking the left and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13027 |
// right vector elements corresponding each segment of the path. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13028 |
// Returns true if a path to sink was found, which means that a unit of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13029 |
// flow was added to the network. The 'seen' vector elements correspond |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13030 |
// to right nodes and are marked to eliminate cycles from the search. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13031 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13032 |
// Left nodes will only be explored at most once because they |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13033 |
// are accessible from at most one right node in the residual flow |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13034 |
// graph. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13035 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13036 |
// Note that left_[ilhs] is the only element of left_ that TryAugment will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13037 |
// potentially transition from kUnused to another value. Any other |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13038 |
// left_ element holding kUnused before TryAugment will be holding it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13039 |
// when TryAugment returns. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13040 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13041 |
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13042 |
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13043 |
if ((*seen)[irhs]) continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13044 |
if (!graph_->HasEdge(ilhs, irhs)) continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13045 |
// There's an available edge from ilhs to irhs. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13046 |
(*seen)[irhs] = 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13047 |
// Next a search is performed to determine whether |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13048 |
// this edge is a dead end or leads to the sink. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13049 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13050 |
// right_[irhs] == kUnused means that there is residual flow from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13051 |
// right node irhs to the sink, so we can use that to finish this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13052 |
// flow path and return success. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13053 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13054 |
// Otherwise there is residual flow to some ilhs. We push flow |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13055 |
// along that path and call ourselves recursively to see if this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13056 |
// ultimately leads to sink. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13057 |
if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13058 |
// Add flow from left_[ilhs] to right_[irhs]. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13059 |
left_[ilhs] = irhs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13060 |
right_[irhs] = ilhs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13061 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13062 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13063 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13064 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13065 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13066 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13067 |
const MatchMatrix* graph_; // not owned |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13068 |
// Each element of the left_ vector represents a left hand side node |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13069 |
// (i.e. an element) and each element of right_ is a right hand side |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13070 |
// node (i.e. a matcher). The values in the left_ vector indicate |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13071 |
// outflow from that node to a node on the right_ side. The values |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13072 |
// in the right_ indicate inflow, and specify which left_ node is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13073 |
// feeding that right_ node, if any. For example, left_[3] == 1 means |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13074 |
// there's a flow from element #3 to matcher #1. Such a flow would also |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13075 |
// be redundantly represented in the right_ vector as right_[1] == 3. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13076 |
// Elements of left_ and right_ are either kUnused or mutually |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13077 |
// referent. Mutually referent means that left_[right_[i]] = i and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13078 |
// right_[left_[i]] = i. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13079 |
::std::vector<size_t> left_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13080 |
::std::vector<size_t> right_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13081 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13082 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13083 |
const size_t MaxBipartiteMatchState::kUnused; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13084 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13085 |
GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13086 |
return MaxBipartiteMatchState(g).Compute(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13087 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13088 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13089 |
static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13090 |
::std::ostream* stream) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13091 |
typedef ElementMatcherPairs::const_iterator Iter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13092 |
::std::ostream& os = *stream; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13093 |
os << "{"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13094 |
const char* sep = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13095 |
for (Iter it = pairs.begin(); it != pairs.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13096 |
os << sep << "\n (" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13097 |
<< "element #" << it->first << ", " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13098 |
<< "matcher #" << it->second << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13099 |
sep = ","; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13100 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13101 |
os << "\n}"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13102 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13103 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13104 |
bool MatchMatrix::NextGraph() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13105 |
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13106 |
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13107 |
char& b = matched_[SpaceIndex(ilhs, irhs)]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13108 |
if (!b) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13109 |
b = 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13110 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13111 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13112 |
b = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13113 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13114 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13115 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13116 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13117 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13118 |
void MatchMatrix::Randomize() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13119 |
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13120 |
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13121 |
char& b = matched_[SpaceIndex(ilhs, irhs)]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13122 |
b = static_cast<char>(rand() & 1); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13123 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13124 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13125 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13126 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13127 |
std::string MatchMatrix::DebugString() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13128 |
::std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13129 |
const char* sep = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13130 |
for (size_t i = 0; i < LhsSize(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13131 |
ss << sep; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13132 |
for (size_t j = 0; j < RhsSize(); ++j) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13133 |
ss << HasEdge(i, j); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13134 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13135 |
sep = ";"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13136 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13137 |
return ss.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13138 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13139 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13140 |
void UnorderedElementsAreMatcherImplBase::DescribeToImpl( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13141 |
::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13142 |
switch (match_flags()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13143 |
case UnorderedMatcherRequire::ExactMatch: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13144 |
if (matcher_describers_.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13145 |
*os << "is empty"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13146 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13147 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13148 |
if (matcher_describers_.size() == 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13149 |
*os << "has " << Elements(1) << " and that element "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13150 |
matcher_describers_[0]->DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13151 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13152 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13153 |
*os << "has " << Elements(matcher_describers_.size()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13154 |
<< " and there exists some permutation of elements such that:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13155 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13156 |
case UnorderedMatcherRequire::Superset: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13157 |
*os << "a surjection from elements to requirements exists such that:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13158 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13159 |
case UnorderedMatcherRequire::Subset: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13160 |
*os << "an injection from elements to requirements exists such that:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13161 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13162 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13163 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13164 |
const char* sep = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13165 |
for (size_t i = 0; i != matcher_describers_.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13166 |
*os << sep; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13167 |
if (match_flags() == UnorderedMatcherRequire::ExactMatch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13168 |
*os << " - element #" << i << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13169 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13170 |
*os << " - an element "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13171 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13172 |
matcher_describers_[i]->DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13173 |
if (match_flags() == UnorderedMatcherRequire::ExactMatch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13174 |
sep = ", and\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13175 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13176 |
sep = "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13177 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13178 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13179 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13180 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13181 |
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13182 |
::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13183 |
switch (match_flags()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13184 |
case UnorderedMatcherRequire::ExactMatch: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13185 |
if (matcher_describers_.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13186 |
*os << "isn't empty"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13187 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13188 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13189 |
if (matcher_describers_.size() == 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13190 |
*os << "doesn't have " << Elements(1) << ", or has " << Elements(1) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13191 |
<< " that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13192 |
matcher_describers_[0]->DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13193 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13194 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13195 |
*os << "doesn't have " << Elements(matcher_describers_.size()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13196 |
<< ", or there exists no permutation of elements such that:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13197 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13198 |
case UnorderedMatcherRequire::Superset: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13199 |
*os << "no surjection from elements to requirements exists such that:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13200 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13201 |
case UnorderedMatcherRequire::Subset: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13202 |
*os << "no injection from elements to requirements exists such that:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13203 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13204 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13205 |
const char* sep = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13206 |
for (size_t i = 0; i != matcher_describers_.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13207 |
*os << sep; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13208 |
if (match_flags() == UnorderedMatcherRequire::ExactMatch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13209 |
*os << " - element #" << i << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13210 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13211 |
*os << " - an element "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13212 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13213 |
matcher_describers_[i]->DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13214 |
if (match_flags() == UnorderedMatcherRequire::ExactMatch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13215 |
sep = ", and\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13216 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13217 |
sep = "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13218 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13219 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13220 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13221 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13222 |
// Checks that all matchers match at least one element, and that all |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13223 |
// elements match at least one matcher. This enables faster matching |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13224 |
// and better error reporting. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13225 |
// Returns false, writing an explanation to 'listener', if and only |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13226 |
// if the success criteria are not met. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13227 |
bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13228 |
const ::std::vector<std::string>& element_printouts, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13229 |
const MatchMatrix& matrix, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13230 |
bool result = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13231 |
::std::vector<char> element_matched(matrix.LhsSize(), 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13232 |
::std::vector<char> matcher_matched(matrix.RhsSize(), 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13233 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13234 |
for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13235 |
for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13236 |
char matched = matrix.HasEdge(ilhs, irhs); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13237 |
element_matched[ilhs] |= matched; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13238 |
matcher_matched[irhs] |= matched; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13239 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13240 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13241 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13242 |
if (match_flags() & UnorderedMatcherRequire::Superset) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13243 |
const char* sep = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13244 |
"where the following matchers don't match any elements:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13245 |
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13246 |
if (matcher_matched[mi]) continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13247 |
result = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13248 |
if (listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13249 |
*listener << sep << "matcher #" << mi << ": "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13250 |
matcher_describers_[mi]->DescribeTo(listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13251 |
sep = ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13252 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13253 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13254 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13255 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13256 |
if (match_flags() & UnorderedMatcherRequire::Subset) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13257 |
const char* sep = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13258 |
"where the following elements don't match any matchers:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13259 |
const char* outer_sep = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13260 |
if (!result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13261 |
outer_sep = "\nand "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13262 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13263 |
for (size_t ei = 0; ei < element_matched.size(); ++ei) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13264 |
if (element_matched[ei]) continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13265 |
result = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13266 |
if (listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13267 |
*listener << outer_sep << sep << "element #" << ei << ": " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13268 |
<< element_printouts[ei]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13269 |
sep = ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13270 |
outer_sep = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13271 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13272 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13273 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13274 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13275 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13276 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13277 |
bool UnorderedElementsAreMatcherImplBase::FindPairing( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13278 |
const MatchMatrix& matrix, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13279 |
ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13280 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13281 |
size_t max_flow = matches.size(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13282 |
if ((match_flags() & UnorderedMatcherRequire::Superset) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13283 |
max_flow < matrix.RhsSize()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13284 |
if (listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13285 |
*listener << "where no permutation of the elements can satisfy all " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13286 |
"matchers, and the closest match is " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13287 |
<< max_flow << " of " << matrix.RhsSize() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13288 |
<< " matchers with the pairings:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13289 |
LogElementMatcherPairVec(matches, listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13290 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13291 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13292 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13293 |
if ((match_flags() & UnorderedMatcherRequire::Subset) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13294 |
max_flow < matrix.LhsSize()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13295 |
if (listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13296 |
*listener |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13297 |
<< "where not all elements can be matched, and the closest match is " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13298 |
<< max_flow << " of " << matrix.RhsSize() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13299 |
<< " matchers with the pairings:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13300 |
LogElementMatcherPairVec(matches, listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13301 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13302 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13303 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13304 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13305 |
if (matches.size() > 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13306 |
if (listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13307 |
const char* sep = "where:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13308 |
for (size_t mi = 0; mi < matches.size(); ++mi) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13309 |
*listener << sep << " - element #" << matches[mi].first |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13310 |
<< " is matched by matcher #" << matches[mi].second; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13311 |
sep = ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13312 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13313 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13314 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13315 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13316 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13317 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13318 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13319 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13320 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13321 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13322 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13323 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13324 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13325 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13326 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13327 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13328 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13329 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13330 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13331 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13332 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13333 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13334 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13335 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13336 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13337 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13338 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13339 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13340 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13341 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13342 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13343 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13344 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13345 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13346 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13347 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13348 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13349 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13350 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13351 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13352 |
// This file implements the spec builder syntax (ON_CALL and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13353 |
// EXPECT_CALL). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13354 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13355 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13356 |
#include <stdlib.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13357 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13358 |
#include <iostream> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13359 |
#include <map> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13360 |
#include <memory> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13361 |
#include <set> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13362 |
#include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13363 |
#include <vector> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13364 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13365 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13366 |
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13367 |
# include <unistd.h> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13368 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13369 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13370 |
// Silence C4800 (C4800: 'int *const ': forcing value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13371 |
// to bool 'true' or 'false') for MSVC 15 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13372 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13373 |
#if _MSC_VER == 1900 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13374 |
# pragma warning(push) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13375 |
# pragma warning(disable:4800) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13376 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13377 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13378 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13379 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13380 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13381 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13382 |
// Protects the mock object registry (in class Mock), all function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13383 |
// mockers, and all expectations. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13384 |
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13385 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13386 |
// Logs a message including file and line number information. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13387 |
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13388 |
const char* file, int line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13389 |
const std::string& message) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13390 |
::std::ostringstream s; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13391 |
s << internal::FormatFileLocation(file, line) << " " << message |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13392 |
<< ::std::endl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13393 |
Log(severity, s.str(), 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13394 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13395 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13396 |
// Constructs an ExpectationBase object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13397 |
ExpectationBase::ExpectationBase(const char* a_file, int a_line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13398 |
const std::string& a_source_text) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13399 |
: file_(a_file), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13400 |
line_(a_line), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13401 |
source_text_(a_source_text), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13402 |
cardinality_specified_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13403 |
cardinality_(Exactly(1)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13404 |
call_count_(0), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13405 |
retired_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13406 |
extra_matcher_specified_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13407 |
repeated_action_specified_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13408 |
retires_on_saturation_(false), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13409 |
last_clause_(kNone), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13410 |
action_count_checked_(false) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13411 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13412 |
// Destructs an ExpectationBase object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13413 |
ExpectationBase::~ExpectationBase() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13414 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13415 |
// Explicitly specifies the cardinality of this expectation. Used by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13416 |
// the subclasses to implement the .Times() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13417 |
void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13418 |
cardinality_specified_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13419 |
cardinality_ = a_cardinality; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13420 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13421 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13422 |
// Retires all pre-requisites of this expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13423 |
void ExpectationBase::RetireAllPreRequisites() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13424 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13425 |
if (is_retired()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13426 |
// We can take this short-cut as we never retire an expectation |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13427 |
// until we have retired all its pre-requisites. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13428 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13429 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13430 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13431 |
::std::vector<ExpectationBase*> expectations(1, this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13432 |
while (!expectations.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13433 |
ExpectationBase* exp = expectations.back(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13434 |
expectations.pop_back(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13435 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13436 |
for (ExpectationSet::const_iterator it = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13437 |
exp->immediate_prerequisites_.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13438 |
it != exp->immediate_prerequisites_.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13439 |
ExpectationBase* next = it->expectation_base().get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13440 |
if (!next->is_retired()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13441 |
next->Retire(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13442 |
expectations.push_back(next); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13443 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13444 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13445 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13446 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13447 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13448 |
// Returns true if and only if all pre-requisites of this expectation |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13449 |
// have been satisfied. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13450 |
bool ExpectationBase::AllPrerequisitesAreSatisfied() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13451 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13452 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13453 |
::std::vector<const ExpectationBase*> expectations(1, this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13454 |
while (!expectations.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13455 |
const ExpectationBase* exp = expectations.back(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13456 |
expectations.pop_back(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13457 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13458 |
for (ExpectationSet::const_iterator it = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13459 |
exp->immediate_prerequisites_.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13460 |
it != exp->immediate_prerequisites_.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13461 |
const ExpectationBase* next = it->expectation_base().get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13462 |
if (!next->IsSatisfied()) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13463 |
expectations.push_back(next); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13464 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13465 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13466 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13467 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13468 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13469 |
// Adds unsatisfied pre-requisites of this expectation to 'result'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13470 |
void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13471 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13472 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13473 |
::std::vector<const ExpectationBase*> expectations(1, this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13474 |
while (!expectations.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13475 |
const ExpectationBase* exp = expectations.back(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13476 |
expectations.pop_back(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13477 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13478 |
for (ExpectationSet::const_iterator it = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13479 |
exp->immediate_prerequisites_.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13480 |
it != exp->immediate_prerequisites_.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13481 |
const ExpectationBase* next = it->expectation_base().get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13482 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13483 |
if (next->IsSatisfied()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13484 |
// If *it is satisfied and has a call count of 0, some of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13485 |
// pre-requisites may not be satisfied yet. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13486 |
if (next->call_count_ == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13487 |
expectations.push_back(next); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13488 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13489 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13490 |
// Now that we know next is unsatisfied, we are not so interested |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13491 |
// in whether its pre-requisites are satisfied. Therefore we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13492 |
// don't iterate into it here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13493 |
*result += *it; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13494 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13495 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13496 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13497 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13498 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13499 |
// Describes how many times a function call matching this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13500 |
// expectation has occurred. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13501 |
void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13502 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13503 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13504 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13505 |
// Describes how many times the function is expected to be called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13506 |
*os << " Expected: to be "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13507 |
cardinality().DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13508 |
*os << "\n Actual: "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13509 |
Cardinality::DescribeActualCallCountTo(call_count(), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13510 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13511 |
// Describes the state of the expectation (e.g. is it satisfied? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13512 |
// is it active?). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13513 |
*os << " - " << (IsOverSaturated() ? "over-saturated" : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13514 |
IsSaturated() ? "saturated" : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13515 |
IsSatisfied() ? "satisfied" : "unsatisfied") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13516 |
<< " and " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13517 |
<< (is_retired() ? "retired" : "active"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13518 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13519 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13520 |
// Checks the action count (i.e. the number of WillOnce() and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13521 |
// WillRepeatedly() clauses) against the cardinality if this hasn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13522 |
// been done before. Prints a warning if there are too many or too |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13523 |
// few actions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13524 |
void ExpectationBase::CheckActionCountIfNotDone() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13525 |
GTEST_LOCK_EXCLUDED_(mutex_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13526 |
bool should_check = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13527 |
{ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13528 |
MutexLock l(&mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13529 |
if (!action_count_checked_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13530 |
action_count_checked_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13531 |
should_check = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13532 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13533 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13534 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13535 |
if (should_check) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13536 |
if (!cardinality_specified_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13537 |
// The cardinality was inferred - no need to check the action |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13538 |
// count against it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13539 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13540 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13541 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13542 |
// The cardinality was explicitly specified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13543 |
const int action_count = static_cast<int>(untyped_actions_.size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13544 |
const int upper_bound = cardinality().ConservativeUpperBound(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13545 |
const int lower_bound = cardinality().ConservativeLowerBound(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13546 |
bool too_many; // True if there are too many actions, or false |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13547 |
// if there are too few. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13548 |
if (action_count > upper_bound || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13549 |
(action_count == upper_bound && repeated_action_specified_)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13550 |
too_many = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13551 |
} else if (0 < action_count && action_count < lower_bound && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13552 |
!repeated_action_specified_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13553 |
too_many = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13554 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13555 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13556 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13557 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13558 |
::std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13559 |
DescribeLocationTo(&ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13560 |
ss << "Too " << (too_many ? "many" : "few") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13561 |
<< " actions specified in " << source_text() << "...\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13562 |
<< "Expected to be "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13563 |
cardinality().DescribeTo(&ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13564 |
ss << ", but has " << (too_many ? "" : "only ") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13565 |
<< action_count << " WillOnce()" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13566 |
<< (action_count == 1 ? "" : "s"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13567 |
if (repeated_action_specified_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13568 |
ss << " and a WillRepeatedly()"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13569 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13570 |
ss << "."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13571 |
Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13572 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13573 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13574 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13575 |
// Implements the .Times() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13576 |
void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13577 |
if (last_clause_ == kTimes) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13578 |
ExpectSpecProperty(false, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13579 |
".Times() cannot appear " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13580 |
"more than once in an EXPECT_CALL()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13581 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13582 |
ExpectSpecProperty(last_clause_ < kTimes, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13583 |
".Times() cannot appear after " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13584 |
".InSequence(), .WillOnce(), .WillRepeatedly(), " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13585 |
"or .RetiresOnSaturation()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13586 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13587 |
last_clause_ = kTimes; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13588 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13589 |
SpecifyCardinality(a_cardinality); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13590 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13591 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13592 |
// Points to the implicit sequence introduced by a living InSequence |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13593 |
// object (if any) in the current thread or NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13594 |
GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13595 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13596 |
// Reports an uninteresting call (whose description is in msg) in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13597 |
// manner specified by 'reaction'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13598 |
void ReportUninterestingCall(CallReaction reaction, const std::string& msg) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13599 |
// Include a stack trace only if --gmock_verbose=info is specified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13600 |
const int stack_frames_to_skip = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13601 |
GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13602 |
switch (reaction) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13603 |
case kAllow: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13604 |
Log(kInfo, msg, stack_frames_to_skip); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13605 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13606 |
case kWarn: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13607 |
Log(kWarning, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13608 |
msg + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13609 |
"\nNOTE: You can safely ignore the above warning unless this " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13610 |
"call should not happen. Do not suppress it by blindly adding " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13611 |
"an EXPECT_CALL() if you don't mean to enforce the call. " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13612 |
"See " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13613 |
"https://github.com/google/googletest/blob/master/docs/" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13614 |
"gmock_cook_book.md#" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13615 |
"knowing-when-to-expect for details.\n", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13616 |
stack_frames_to_skip); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13617 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13618 |
default: // FAIL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13619 |
Expect(false, nullptr, -1, msg); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13620 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13621 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13622 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13623 |
UntypedFunctionMockerBase::UntypedFunctionMockerBase() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13624 |
: mock_obj_(nullptr), name_("") {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13625 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13626 |
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13627 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13628 |
// Sets the mock object this mock method belongs to, and registers |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13629 |
// this information in the global mock registry. Will be called |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13630 |
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13631 |
// method. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13632 |
void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13633 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13634 |
{ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13635 |
MutexLock l(&g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13636 |
mock_obj_ = mock_obj; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13637 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13638 |
Mock::Register(mock_obj, this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13639 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13640 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13641 |
// Sets the mock object this mock method belongs to, and sets the name |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13642 |
// of the mock function. Will be called upon each invocation of this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13643 |
// mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13644 |
void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13645 |
const char* name) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13646 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13647 |
// We protect name_ under g_gmock_mutex in case this mock function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13648 |
// is called from two threads concurrently. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13649 |
MutexLock l(&g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13650 |
mock_obj_ = mock_obj; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13651 |
name_ = name; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13652 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13653 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13654 |
// Returns the name of the function being mocked. Must be called |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13655 |
// after RegisterOwner() or SetOwnerAndName() has been called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13656 |
const void* UntypedFunctionMockerBase::MockObject() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13657 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13658 |
const void* mock_obj; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13659 |
{ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13660 |
// We protect mock_obj_ under g_gmock_mutex in case this mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13661 |
// function is called from two threads concurrently. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13662 |
MutexLock l(&g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13663 |
Assert(mock_obj_ != nullptr, __FILE__, __LINE__, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13664 |
"MockObject() must not be called before RegisterOwner() or " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13665 |
"SetOwnerAndName() has been called."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13666 |
mock_obj = mock_obj_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13667 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13668 |
return mock_obj; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13669 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13670 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13671 |
// Returns the name of this mock method. Must be called after |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13672 |
// SetOwnerAndName() has been called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13673 |
const char* UntypedFunctionMockerBase::Name() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13674 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13675 |
const char* name; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13676 |
{ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13677 |
// We protect name_ under g_gmock_mutex in case this mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13678 |
// function is called from two threads concurrently. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13679 |
MutexLock l(&g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13680 |
Assert(name_ != nullptr, __FILE__, __LINE__, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13681 |
"Name() must not be called before SetOwnerAndName() has " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13682 |
"been called."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13683 |
name = name_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13684 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13685 |
return name; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13686 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13687 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13688 |
// Calculates the result of invoking this mock function with the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13689 |
// arguments, prints it, and returns it. The caller is responsible |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13690 |
// for deleting the result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13691 |
UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13692 |
void* const untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13693 |
// See the definition of untyped_expectations_ for why access to it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13694 |
// is unprotected here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13695 |
if (untyped_expectations_.size() == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13696 |
// No expectation is set on this mock method - we have an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13697 |
// uninteresting call. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13698 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13699 |
// We must get Google Mock's reaction on uninteresting calls |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13700 |
// made on this mock object BEFORE performing the action, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13701 |
// because the action may DELETE the mock object and make the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13702 |
// following expression meaningless. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13703 |
const CallReaction reaction = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13704 |
Mock::GetReactionOnUninterestingCalls(MockObject()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13705 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13706 |
// True if and only if we need to print this call's arguments and return |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13707 |
// value. This definition must be kept in sync with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13708 |
// the behavior of ReportUninterestingCall(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13709 |
const bool need_to_report_uninteresting_call = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13710 |
// If the user allows this uninteresting call, we print it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13711 |
// only when they want informational messages. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13712 |
reaction == kAllow ? LogIsVisible(kInfo) : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13713 |
// If the user wants this to be a warning, we print |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13714 |
// it only when they want to see warnings. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13715 |
reaction == kWarn |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13716 |
? LogIsVisible(kWarning) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13717 |
: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13718 |
// Otherwise, the user wants this to be an error, and we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13719 |
// should always print detailed information in the error. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13720 |
true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13721 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13722 |
if (!need_to_report_uninteresting_call) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13723 |
// Perform the action without printing the call information. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13724 |
return this->UntypedPerformDefaultAction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13725 |
untyped_args, "Function call: " + std::string(Name())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13726 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13727 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13728 |
// Warns about the uninteresting call. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13729 |
::std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13730 |
this->UntypedDescribeUninterestingCall(untyped_args, &ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13731 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13732 |
// Calculates the function result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13733 |
UntypedActionResultHolderBase* const result = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13734 |
this->UntypedPerformDefaultAction(untyped_args, ss.str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13735 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13736 |
// Prints the function result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13737 |
if (result != nullptr) result->PrintAsActionResult(&ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13738 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13739 |
ReportUninterestingCall(reaction, ss.str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13740 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13741 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13742 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13743 |
bool is_excessive = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13744 |
::std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13745 |
::std::stringstream why; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13746 |
::std::stringstream loc; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13747 |
const void* untyped_action = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13748 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13749 |
// The UntypedFindMatchingExpectation() function acquires and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13750 |
// releases g_gmock_mutex. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13751 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13752 |
const ExpectationBase* const untyped_expectation = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13753 |
this->UntypedFindMatchingExpectation(untyped_args, &untyped_action, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13754 |
&is_excessive, &ss, &why); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13755 |
const bool found = untyped_expectation != nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13756 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13757 |
// True if and only if we need to print the call's arguments |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13758 |
// and return value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13759 |
// This definition must be kept in sync with the uses of Expect() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13760 |
// and Log() in this function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13761 |
const bool need_to_report_call = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13762 |
!found || is_excessive || LogIsVisible(kInfo); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13763 |
if (!need_to_report_call) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13764 |
// Perform the action without printing the call information. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13765 |
return untyped_action == nullptr |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13766 |
? this->UntypedPerformDefaultAction(untyped_args, "") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13767 |
: this->UntypedPerformAction(untyped_action, untyped_args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13768 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13769 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13770 |
ss << " Function call: " << Name(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13771 |
this->UntypedPrintArgs(untyped_args, &ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13772 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13773 |
// In case the action deletes a piece of the expectation, we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13774 |
// generate the message beforehand. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13775 |
if (found && !is_excessive) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13776 |
untyped_expectation->DescribeLocationTo(&loc); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13777 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13778 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13779 |
UntypedActionResultHolderBase* result = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13780 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13781 |
auto perform_action = [&] { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13782 |
return untyped_action == nullptr |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13783 |
? this->UntypedPerformDefaultAction(untyped_args, ss.str()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13784 |
: this->UntypedPerformAction(untyped_action, untyped_args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13785 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13786 |
auto handle_failures = [&] { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13787 |
ss << "\n" << why.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13788 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13789 |
if (!found) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13790 |
// No expectation matches this call - reports a failure. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13791 |
Expect(false, nullptr, -1, ss.str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13792 |
} else if (is_excessive) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13793 |
// We had an upper-bound violation and the failure message is in ss. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13794 |
Expect(false, untyped_expectation->file(), untyped_expectation->line(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13795 |
ss.str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13796 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13797 |
// We had an expected call and the matching expectation is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13798 |
// described in ss. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13799 |
Log(kInfo, loc.str() + ss.str(), 2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13800 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13801 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13802 |
#if GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13803 |
try { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13804 |
result = perform_action(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13805 |
} catch (...) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13806 |
handle_failures(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13807 |
throw; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13808 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13809 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13810 |
result = perform_action(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13811 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13812 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13813 |
if (result != nullptr) result->PrintAsActionResult(&ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13814 |
handle_failures(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13815 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13816 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13817 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13818 |
// Returns an Expectation object that references and co-owns exp, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13819 |
// which must be an expectation on this mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13820 |
Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13821 |
// See the definition of untyped_expectations_ for why access to it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13822 |
// is unprotected here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13823 |
for (UntypedExpectations::const_iterator it = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13824 |
untyped_expectations_.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13825 |
it != untyped_expectations_.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13826 |
if (it->get() == exp) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13827 |
return Expectation(*it); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13828 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13829 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13830 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13831 |
Assert(false, __FILE__, __LINE__, "Cannot find expectation."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13832 |
return Expectation(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13833 |
// The above statement is just to make the code compile, and will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13834 |
// never be executed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13835 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13836 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13837 |
// Verifies that all expectations on this mock function have been |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13838 |
// satisfied. Reports one or more Google Test non-fatal failures |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13839 |
// and returns false if not. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13840 |
bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13841 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13842 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13843 |
bool expectations_met = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13844 |
for (UntypedExpectations::const_iterator it = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13845 |
untyped_expectations_.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13846 |
it != untyped_expectations_.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13847 |
ExpectationBase* const untyped_expectation = it->get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13848 |
if (untyped_expectation->IsOverSaturated()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13849 |
// There was an upper-bound violation. Since the error was |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13850 |
// already reported when it occurred, there is no need to do |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13851 |
// anything here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13852 |
expectations_met = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13853 |
} else if (!untyped_expectation->IsSatisfied()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13854 |
expectations_met = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13855 |
::std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13856 |
ss << "Actual function call count doesn't match " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13857 |
<< untyped_expectation->source_text() << "...\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13858 |
// No need to show the source file location of the expectation |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13859 |
// in the description, as the Expect() call that follows already |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13860 |
// takes care of it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13861 |
untyped_expectation->MaybeDescribeExtraMatcherTo(&ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13862 |
untyped_expectation->DescribeCallCountTo(&ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13863 |
Expect(false, untyped_expectation->file(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13864 |
untyped_expectation->line(), ss.str()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13865 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13866 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13867 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13868 |
// Deleting our expectations may trigger other mock objects to be deleted, for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13869 |
// example if an action contains a reference counted smart pointer to that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13870 |
// mock object, and that is the last reference. So if we delete our |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13871 |
// expectations within the context of the global mutex we may deadlock when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13872 |
// this method is called again. Instead, make a copy of the set of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13873 |
// expectations to delete, clear our set within the mutex, and then clear the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13874 |
// copied set outside of it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13875 |
UntypedExpectations expectations_to_delete; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13876 |
untyped_expectations_.swap(expectations_to_delete); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13877 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13878 |
g_gmock_mutex.Unlock(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13879 |
expectations_to_delete.clear(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13880 |
g_gmock_mutex.Lock(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13881 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13882 |
return expectations_met; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13883 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13884 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13885 |
CallReaction intToCallReaction(int mock_behavior) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13886 |
if (mock_behavior >= kAllow && mock_behavior <= kFail) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13887 |
return static_cast<internal::CallReaction>(mock_behavior); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13888 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13889 |
return kWarn; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13890 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13891 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13892 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13893 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13894 |
// Class Mock. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13895 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13896 |
namespace { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13897 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13898 |
typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13899 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13900 |
// The current state of a mock object. Such information is needed for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13901 |
// detecting leaked mock objects and explicitly verifying a mock's |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13902 |
// expectations. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13903 |
struct MockObjectState { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13904 |
MockObjectState() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13905 |
: first_used_file(nullptr), first_used_line(-1), leakable(false) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13906 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13907 |
// Where in the source file an ON_CALL or EXPECT_CALL is first |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13908 |
// invoked on this mock object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13909 |
const char* first_used_file; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13910 |
int first_used_line; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13911 |
::std::string first_used_test_suite; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13912 |
::std::string first_used_test; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13913 |
bool leakable; // true if and only if it's OK to leak the object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13914 |
FunctionMockers function_mockers; // All registered methods of the object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13915 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13916 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13917 |
// A global registry holding the state of all mock objects that are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13918 |
// alive. A mock object is added to this registry the first time |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13919 |
// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13920 |
// is removed from the registry in the mock object's destructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13921 |
class MockObjectRegistry { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13922 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13923 |
// Maps a mock object (identified by its address) to its state. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13924 |
typedef std::map<const void*, MockObjectState> StateMap; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13925 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13926 |
// This destructor will be called when a program exits, after all |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13927 |
// tests in it have been run. By then, there should be no mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13928 |
// object alive. Therefore we report any living object as test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13929 |
// failure, unless the user explicitly asked us to ignore it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13930 |
~MockObjectRegistry() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13931 |
if (!GMOCK_FLAG(catch_leaked_mocks)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13932 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13933 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13934 |
int leaked_count = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13935 |
for (StateMap::const_iterator it = states_.begin(); it != states_.end(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13936 |
++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13937 |
if (it->second.leakable) // The user said it's fine to leak this object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13938 |
continue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13939 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13940 |
// FIXME: Print the type of the leaked object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13941 |
// This can help the user identify the leaked object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13942 |
std::cout << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13943 |
const MockObjectState& state = it->second; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13944 |
std::cout << internal::FormatFileLocation(state.first_used_file, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13945 |
state.first_used_line); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13946 |
std::cout << " ERROR: this mock object"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13947 |
if (state.first_used_test != "") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13948 |
std::cout << " (used in test " << state.first_used_test_suite << "." |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13949 |
<< state.first_used_test << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13950 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13951 |
std::cout << " should be deleted but never is. Its address is @" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13952 |
<< it->first << "."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13953 |
leaked_count++; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13954 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13955 |
if (leaked_count > 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13956 |
std::cout << "\nERROR: " << leaked_count << " leaked mock " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13957 |
<< (leaked_count == 1 ? "object" : "objects") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13958 |
<< " found at program exit. Expectations on a mock object are " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13959 |
"verified when the object is destructed. Leaking a mock " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13960 |
"means that its expectations aren't verified, which is " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13961 |
"usually a test bug. If you really intend to leak a mock, " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13962 |
"you can suppress this error using " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13963 |
"testing::Mock::AllowLeak(mock_object), or you may use a " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13964 |
"fake or stub instead of a mock.\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13965 |
std::cout.flush(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13966 |
::std::cerr.flush(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13967 |
// RUN_ALL_TESTS() has already returned when this destructor is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13968 |
// called. Therefore we cannot use the normal Google Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13969 |
// failure reporting mechanism. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13970 |
_exit(1); // We cannot call exit() as it is not reentrant and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13971 |
// may already have been called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13972 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13973 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13974 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13975 |
StateMap& states() { return states_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13976 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13977 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13978 |
StateMap states_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13979 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13980 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13981 |
// Protected by g_gmock_mutex. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13982 |
MockObjectRegistry g_mock_object_registry; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13983 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13984 |
// Maps a mock object to the reaction Google Mock should have when an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13985 |
// uninteresting method is called. Protected by g_gmock_mutex. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13986 |
std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13987 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13988 |
// Sets the reaction Google Mock should have when an uninteresting |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13989 |
// method of the given mock object is called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13990 |
void SetReactionOnUninterestingCalls(const void* mock_obj, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13991 |
internal::CallReaction reaction) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13992 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13993 |
internal::MutexLock l(&internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13994 |
g_uninteresting_call_reaction[mock_obj] = reaction; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13995 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13996 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13997 |
} // namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13998 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13999 |
// Tells Google Mock to allow uninteresting calls on the given mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14000 |
// object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14001 |
void Mock::AllowUninterestingCalls(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14002 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14003 |
SetReactionOnUninterestingCalls(mock_obj, internal::kAllow); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14004 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14005 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14006 |
// Tells Google Mock to warn the user about uninteresting calls on the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14007 |
// given mock object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14008 |
void Mock::WarnUninterestingCalls(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14009 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14010 |
SetReactionOnUninterestingCalls(mock_obj, internal::kWarn); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14011 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14012 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14013 |
// Tells Google Mock to fail uninteresting calls on the given mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14014 |
// object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14015 |
void Mock::FailUninterestingCalls(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14016 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14017 |
SetReactionOnUninterestingCalls(mock_obj, internal::kFail); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14018 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14019 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14020 |
// Tells Google Mock the given mock object is being destroyed and its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14021 |
// entry in the call-reaction table should be removed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14022 |
void Mock::UnregisterCallReaction(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14023 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14024 |
internal::MutexLock l(&internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14025 |
g_uninteresting_call_reaction.erase(mock_obj); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14026 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14027 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14028 |
// Returns the reaction Google Mock will have on uninteresting calls |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14029 |
// made on the given mock object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14030 |
internal::CallReaction Mock::GetReactionOnUninterestingCalls( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14031 |
const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14032 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14033 |
internal::MutexLock l(&internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14034 |
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14035 |
internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14036 |
g_uninteresting_call_reaction[mock_obj]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14037 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14038 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14039 |
// Tells Google Mock to ignore mock_obj when checking for leaked mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14040 |
// objects. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14041 |
void Mock::AllowLeak(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14042 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14043 |
internal::MutexLock l(&internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14044 |
g_mock_object_registry.states()[mock_obj].leakable = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14045 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14046 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14047 |
// Verifies and clears all expectations on the given mock object. If |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14048 |
// the expectations aren't satisfied, generates one or more Google |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14049 |
// Test non-fatal failures and returns false. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14050 |
bool Mock::VerifyAndClearExpectations(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14051 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14052 |
internal::MutexLock l(&internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14053 |
return VerifyAndClearExpectationsLocked(mock_obj); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14054 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14055 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14056 |
// Verifies all expectations on the given mock object and clears its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14057 |
// default actions and expectations. Returns true if and only if the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14058 |
// verification was successful. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14059 |
bool Mock::VerifyAndClear(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14060 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14061 |
internal::MutexLock l(&internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14062 |
ClearDefaultActionsLocked(mock_obj); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14063 |
return VerifyAndClearExpectationsLocked(mock_obj); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14064 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14065 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14066 |
// Verifies and clears all expectations on the given mock object. If |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14067 |
// the expectations aren't satisfied, generates one or more Google |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14068 |
// Test non-fatal failures and returns false. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14069 |
bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14070 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14071 |
internal::g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14072 |
if (g_mock_object_registry.states().count(mock_obj) == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14073 |
// No EXPECT_CALL() was set on the given mock object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14074 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14075 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14076 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14077 |
// Verifies and clears the expectations on each mock method in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14078 |
// given mock object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14079 |
bool expectations_met = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14080 |
FunctionMockers& mockers = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14081 |
g_mock_object_registry.states()[mock_obj].function_mockers; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14082 |
for (FunctionMockers::const_iterator it = mockers.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14083 |
it != mockers.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14084 |
if (!(*it)->VerifyAndClearExpectationsLocked()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14085 |
expectations_met = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14086 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14087 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14088 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14089 |
// We don't clear the content of mockers, as they may still be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14090 |
// needed by ClearDefaultActionsLocked(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14091 |
return expectations_met; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14092 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14093 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14094 |
bool Mock::IsNaggy(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14095 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14096 |
return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kWarn; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14097 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14098 |
bool Mock::IsNice(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14099 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14100 |
return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kAllow; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14101 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14102 |
bool Mock::IsStrict(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14103 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14104 |
return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kFail; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14105 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14106 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14107 |
// Registers a mock object and a mock method it owns. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14108 |
void Mock::Register(const void* mock_obj, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14109 |
internal::UntypedFunctionMockerBase* mocker) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14110 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14111 |
internal::MutexLock l(&internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14112 |
g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14113 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14114 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14115 |
// Tells Google Mock where in the source code mock_obj is used in an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14116 |
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14117 |
// information helps the user identify which object it is. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14118 |
void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14119 |
const char* file, int line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14120 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14121 |
internal::MutexLock l(&internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14122 |
MockObjectState& state = g_mock_object_registry.states()[mock_obj]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14123 |
if (state.first_used_file == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14124 |
state.first_used_file = file; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14125 |
state.first_used_line = line; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14126 |
const TestInfo* const test_info = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14127 |
UnitTest::GetInstance()->current_test_info(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14128 |
if (test_info != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14129 |
state.first_used_test_suite = test_info->test_suite_name(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14130 |
state.first_used_test = test_info->name(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14131 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14132 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14133 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14134 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14135 |
// Unregisters a mock method; removes the owning mock object from the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14136 |
// registry when the last mock method associated with it has been |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14137 |
// unregistered. This is called only in the destructor of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14138 |
// FunctionMockerBase. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14139 |
void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14140 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14141 |
internal::g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14142 |
for (MockObjectRegistry::StateMap::iterator it = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14143 |
g_mock_object_registry.states().begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14144 |
it != g_mock_object_registry.states().end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14145 |
FunctionMockers& mockers = it->second.function_mockers; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14146 |
if (mockers.erase(mocker) > 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14147 |
// mocker was in mockers and has been just removed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14148 |
if (mockers.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14149 |
g_mock_object_registry.states().erase(it); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14150 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14151 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14152 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14153 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14154 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14155 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14156 |
// Clears all ON_CALL()s set on the given mock object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14157 |
void Mock::ClearDefaultActionsLocked(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14158 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14159 |
internal::g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14160 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14161 |
if (g_mock_object_registry.states().count(mock_obj) == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14162 |
// No ON_CALL() was set on the given mock object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14163 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14164 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14165 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14166 |
// Clears the default actions for each mock method in the given mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14167 |
// object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14168 |
FunctionMockers& mockers = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14169 |
g_mock_object_registry.states()[mock_obj].function_mockers; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14170 |
for (FunctionMockers::const_iterator it = mockers.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14171 |
it != mockers.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14172 |
(*it)->ClearDefaultActionsLocked(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14173 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14174 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14175 |
// We don't clear the content of mockers, as they may still be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14176 |
// needed by VerifyAndClearExpectationsLocked(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14177 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14178 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14179 |
Expectation::Expectation() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14180 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14181 |
Expectation::Expectation( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14182 |
const std::shared_ptr<internal::ExpectationBase>& an_expectation_base) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14183 |
: expectation_base_(an_expectation_base) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14184 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14185 |
Expectation::~Expectation() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14186 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14187 |
// Adds an expectation to a sequence. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14188 |
void Sequence::AddExpectation(const Expectation& expectation) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14189 |
if (*last_expectation_ != expectation) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14190 |
if (last_expectation_->expectation_base() != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14191 |
expectation.expectation_base()->immediate_prerequisites_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14192 |
+= *last_expectation_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14193 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14194 |
*last_expectation_ = expectation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14195 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14196 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14197 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14198 |
// Creates the implicit sequence if there isn't one. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14199 |
InSequence::InSequence() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14200 |
if (internal::g_gmock_implicit_sequence.get() == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14201 |
internal::g_gmock_implicit_sequence.set(new Sequence); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14202 |
sequence_created_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14203 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14204 |
sequence_created_ = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14205 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14206 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14207 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14208 |
// Deletes the implicit sequence if it was created by the constructor |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14209 |
// of this object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14210 |
InSequence::~InSequence() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14211 |
if (sequence_created_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14212 |
delete internal::g_gmock_implicit_sequence.get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14213 |
internal::g_gmock_implicit_sequence.set(nullptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14214 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14215 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14216 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14217 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14218 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14219 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14220 |
#if _MSC_VER == 1900 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14221 |
# pragma warning(pop) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14222 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14223 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14224 |
// Copyright 2008, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14225 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14226 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14227 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14228 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14229 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14230 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14231 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14232 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14233 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14234 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14235 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14236 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14237 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14238 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14239 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14240 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14241 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14242 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14243 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14244 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14245 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14246 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14247 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14248 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14249 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14250 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14251 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14252 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14253 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14254 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14255 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14256 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14257 |
GMOCK_DEFINE_bool_(catch_leaked_mocks, true, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14258 |
"true if and only if Google Mock should report leaked " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14259 |
"mock objects as failures."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14260 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14261 |
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14262 |
"Controls how verbose Google Mock's output is." |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14263 |
" Valid values:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14264 |
" info - prints all messages.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14265 |
" warning - prints warnings and errors.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14266 |
" error - prints errors only."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14267 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14268 |
GMOCK_DEFINE_int32_(default_mock_behavior, 1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14269 |
"Controls the default behavior of mocks." |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14270 |
" Valid values:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14271 |
" 0 - by default, mocks act as NiceMocks.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14272 |
" 1 - by default, mocks act as NaggyMocks.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14273 |
" 2 - by default, mocks act as StrictMocks."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14274 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14275 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14276 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14277 |
// Parses a string as a command line flag. The string should have the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14278 |
// format "--gmock_flag=value". When def_optional is true, the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14279 |
// "=value" part can be omitted. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14280 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14281 |
// Returns the value of the flag, or NULL if the parsing failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14282 |
static const char* ParseGoogleMockFlagValue(const char* str, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14283 |
const char* flag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14284 |
bool def_optional) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14285 |
// str and flag must not be NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14286 |
if (str == nullptr || flag == nullptr) return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14287 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14288 |
// The flag must start with "--gmock_". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14289 |
const std::string flag_str = std::string("--gmock_") + flag; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14290 |
const size_t flag_len = flag_str.length(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14291 |
if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14292 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14293 |
// Skips the flag name. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14294 |
const char* flag_end = str + flag_len; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14295 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14296 |
// When def_optional is true, it's OK to not have a "=value" part. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14297 |
if (def_optional && (flag_end[0] == '\0')) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14298 |
return flag_end; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14299 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14300 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14301 |
// If def_optional is true and there are more characters after the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14302 |
// flag name, or if def_optional is false, there must be a '=' after |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14303 |
// the flag name. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14304 |
if (flag_end[0] != '=') return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14305 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14306 |
// Returns the string after "=". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14307 |
return flag_end + 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14308 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14309 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14310 |
// Parses a string for a Google Mock bool flag, in the form of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14311 |
// "--gmock_flag=value". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14312 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14313 |
// On success, stores the value of the flag in *value, and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14314 |
// true. On failure, returns false without changing *value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14315 |
static bool ParseGoogleMockBoolFlag(const char* str, const char* flag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14316 |
bool* value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14317 |
// Gets the value of the flag as a string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14318 |
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14319 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14320 |
// Aborts if the parsing failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14321 |
if (value_str == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14322 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14323 |
// Converts the string value to a bool. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14324 |
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14325 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14326 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14327 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14328 |
// Parses a string for a Google Mock string flag, in the form of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14329 |
// "--gmock_flag=value". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14330 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14331 |
// On success, stores the value of the flag in *value, and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14332 |
// true. On failure, returns false without changing *value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14333 |
template <typename String> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14334 |
static bool ParseGoogleMockStringFlag(const char* str, const char* flag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14335 |
String* value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14336 |
// Gets the value of the flag as a string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14337 |
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14338 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14339 |
// Aborts if the parsing failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14340 |
if (value_str == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14341 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14342 |
// Sets *value to the value of the flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14343 |
*value = value_str; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14344 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14345 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14346 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14347 |
static bool ParseGoogleMockIntFlag(const char* str, const char* flag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14348 |
int32_t* value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14349 |
// Gets the value of the flag as a string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14350 |
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14351 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14352 |
// Aborts if the parsing failed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14353 |
if (value_str == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14354 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14355 |
// Sets *value to the value of the flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14356 |
return ParseInt32(Message() << "The value of flag --" << flag, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14357 |
value_str, value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14358 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14359 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14360 |
// The internal implementation of InitGoogleMock(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14361 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14362 |
// The type parameter CharType can be instantiated to either char or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14363 |
// wchar_t. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14364 |
template <typename CharType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14365 |
void InitGoogleMockImpl(int* argc, CharType** argv) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14366 |
// Makes sure Google Test is initialized. InitGoogleTest() is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14367 |
// idempotent, so it's fine if the user has already called it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14368 |
InitGoogleTest(argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14369 |
if (*argc <= 0) return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14370 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14371 |
for (int i = 1; i != *argc; i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14372 |
const std::string arg_string = StreamableToString(argv[i]); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14373 |
const char* const arg = arg_string.c_str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14374 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14375 |
// Do we see a Google Mock flag? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14376 |
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14377 |
&GMOCK_FLAG(catch_leaked_mocks)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14378 |
ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14379 |
ParseGoogleMockIntFlag(arg, "default_mock_behavior", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14380 |
&GMOCK_FLAG(default_mock_behavior))) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14381 |
// Yes. Shift the remainder of the argv list left by one. Note |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14382 |
// that argv has (*argc + 1) elements, the last one always being |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14383 |
// NULL. The following loop moves the trailing NULL element as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14384 |
// well. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14385 |
for (int j = i; j != *argc; j++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14386 |
argv[j] = argv[j + 1]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14387 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14388 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14389 |
// Decrements the argument count. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14390 |
(*argc)--; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14391 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14392 |
// We also need to decrement the iterator as we just removed |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14393 |
// an element. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14394 |
i--; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14395 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14396 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14397 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14398 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14399 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14400 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14401 |
// Initializes Google Mock. This must be called before running the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14402 |
// tests. In particular, it parses a command line for the flags that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14403 |
// Google Mock recognizes. Whenever a Google Mock flag is seen, it is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14404 |
// removed from argv, and *argc is decremented. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14405 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14406 |
// No value is returned. Instead, the Google Mock flag variables are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14407 |
// updated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14408 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14409 |
// Since Google Test is needed for Google Mock to work, this function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14410 |
// also initializes Google Test and parses its flags, if that hasn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14411 |
// been done. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14412 |
GTEST_API_ void InitGoogleMock(int* argc, char** argv) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14413 |
internal::InitGoogleMockImpl(argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14414 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14415 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14416 |
// This overloaded version can be used in Windows programs compiled in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14417 |
// UNICODE mode. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14418 |
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14419 |
internal::InitGoogleMockImpl(argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14420 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14421 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14422 |
// This overloaded version can be used on Arduino/embedded platforms where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14423 |
// there is no argc/argv. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14424 |
GTEST_API_ void InitGoogleMock() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14425 |
// Since Arduino doesn't have a command line, fake out the argc/argv arguments |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14426 |
int argc = 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14427 |
const auto arg0 = "dummy"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14428 |
char* argv0 = const_cast<char*>(arg0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14429 |
char** argv = &argv0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14430 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14431 |
internal::InitGoogleMockImpl(&argc, argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14432 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14433 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14434 |
} // namespace testing |
|
|
1970-01-01 00:00 |
14435 |
|