1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 // Macros for use in enabling/disabling tests on particular
17 // platforms. Marking a gunit test as disabled still ensures that it
18 // compiles.
19 //
20 // Implementation note: the macros are structured as follows:
21 // * Define the disabled macro to just pass the test name through (which, in
22 //   effect, does not disable it at all)
23 // * If a XLA_TEST_BACKEND_$TARGET macro indicates we're compiling for
24 //   $TARGET platform, make the disabled macro truly disable the test; i.e. by
25 //   redefining the DISABLED_ON_$TARGET macro to prepend "DISABLED_" to the test
26 //   name.
27 
28 #ifndef TENSORFLOW_COMPILER_XLA_TESTS_TEST_MACROS_H_
29 #define TENSORFLOW_COMPILER_XLA_TESTS_TEST_MACROS_H_
30 
31 #include <string>
32 
33 #include "tensorflow/compiler/xla/types.h"
34 #include "tensorflow/core/platform/test.h"
35 
36 #define DISABLED_ON_CPU(X) X
37 #define DISABLED_ON_GPU(X) X
38 #define DISABLED_ON_INTERPRETER(X) X
39 
40 // We need this macro instead of pasting directly to support nesting
41 // the DISABLED_ON_FOO macros, as in the definition of DISABLED_ON_CPU.
42 // Otherwise the pasting is applied before macro expansion completes.
43 #define XLA_TEST_PASTE(A, B) A##B
44 
45 // We turn off clang-format so we can indent the macros for readability.
46 // clang-format off
47 
48 #ifdef XLA_TEST_BACKEND_CPU
49 # undef DISABLED_ON_CPU
50 # define DISABLED_ON_CPU(X) XLA_TEST_PASTE(DISABLED_, X)
51 #endif  // XLA_TEST_BACKEND_CPU
52 
53 #ifdef XLA_TEST_BACKEND_GPU
54 # undef DISABLED_ON_GPU
55 # define DISABLED_ON_GPU(X) XLA_TEST_PASTE(DISABLED_, X)
56 #endif  // XLA_TEST_BACKEND_GPU
57 
58 #ifdef XLA_TEST_BACKEND_INTERPRETER
59 # undef DISABLED_ON_INTERPRETER
60 # define DISABLED_ON_INTERPRETER(X) XLA_TEST_PASTE(DISABLED_, X)
61 #endif  // XLA_TEST_BACKEND_INTERPRETER
62 
63 // clang-format on
64 
65 namespace xla {
66 
67 // Reads a disabled manifest file to resolve whether test cases should be
68 // disabled on a particular platform. For a test that should be disabled,
69 // returns DISABLED_ prepended to its name; otherwise returns the test name
70 // unmodified.
71 string PrependDisabledIfIndicated(const string& test_case_name,
72                                   const string& test_name);
73 
74 }  // namespace xla
75 
76 // This is the internal "gtest" class instantiation -- it is identical to the
77 // GTEST_TEST_ macro, except that we intercept the test name for potential
78 // modification by PrependDisabledIfIndicated. That file can use an arbitrary
79 // heuristic to decide whether the test case should be disabled, and we
80 // determine whether the test case should be disabled by resolving the (test
81 // case name, test name) in a manifest file.
82 #define XLA_GTEST_TEST_(test_case_name, test_name, parent_class)             \
83   class GTEST_TEST_CLASS_NAME_(test_case_name, test_name)                    \
84       : public parent_class {                                                \
85    public:                                                                   \
86     GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}                   \
87                                                                              \
88    private:                                                                  \
89     virtual void TestBody();                                                 \
90     static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;    \
91     GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_case_name,   \
92                                                            test_name));      \
93   };                                                                         \
94                                                                              \
95   ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name,          \
96                                                     test_name)::test_info_ = \
97       ::testing::RegisterTest(                                               \
98           #test_case_name,                                                   \
99           ::xla::PrependDisabledIfIndicated(#test_case_name, #test_name)     \
100               .c_str(),                                                      \
101           nullptr, nullptr, __FILE__, __LINE__, []() -> parent_class* {      \
102             return new GTEST_TEST_CLASS_NAME_(test_case_name, test_name)();  \
103           });                                                                \
104   void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
105 
106 // This is identical to the TEST_F macro from "gtest", but it potentially
107 // disables the test based on an external manifest file, DISABLED_MANIFEST.
108 //
109 // Per usual, you can see what tests are available via --gunit_list_tests and
110 // choose to run tests that have been disabled via the manifest via
111 // --gunit_also_run_disabled_tests.
112 #define XLA_TEST_F(test_fixture, test_name) \
113   XLA_GTEST_TEST_(test_fixture, test_name, test_fixture)
114 
115 // Likewise, this is identical to the TEST_P macro from "gtest", but
116 // potentially disables the test based on the DISABLED_MANIFEST file.
117 //
118 // We have to wrap this in an outer layer so that any DISABLED_ON_* macros will
119 // be properly expanded before the stringification occurs.
120 #define XLA_TEST_P_IMPL_(test_case_name, test_name)                            \
121   class GTEST_TEST_CLASS_NAME_(test_case_name, test_name)                      \
122       : public test_case_name {                                                \
123    public:                                                                     \
124     GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}                     \
125     virtual void TestBody();                                                   \
126                                                                                \
127    private:                                                                    \
128     static int AddToRegistry() {                                               \
129       ::testing::UnitTest::GetInstance()                                       \
130           ->parameterized_test_registry()                                      \
131           .GetTestCasePatternHolder<test_case_name>(                           \
132               #test_case_name,                                                 \
133               ::testing::internal::CodeLocation(__FILE__, __LINE__))           \
134           ->AddTestPattern(                                                    \
135               #test_case_name,                                                 \
136               ::xla::PrependDisabledIfIndicated(#test_case_name, #test_name)   \
137                   .c_str(),                                                    \
138               new ::testing::internal::TestMetaFactory<GTEST_TEST_CLASS_NAME_( \
139                   test_case_name, test_name)>());                              \
140       return 0;                                                                \
141     }                                                                          \
142     static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_;               \
143     GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_case_name,     \
144                                                            test_name));        \
145   };                                                                           \
146   int GTEST_TEST_CLASS_NAME_(test_case_name,                                   \
147                              test_name)::gtest_registering_dummy_ =            \
148       GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry();      \
149   void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
150 
151 #define XLA_TEST_P(test_case_name, test_name) \
152   XLA_TEST_P_IMPL_(test_case_name, test_name)
153 
154 // This is identical to the TEST_F macro from "gtest", but it potentially
155 // disables the test based on an external manifest file, DISABLED_MANIFEST.
156 #define XLA_TYPED_TEST(CaseName, TestName)                                     \
157   template <typename gtest_TypeParam_>                                         \
158   class GTEST_TEST_CLASS_NAME_(CaseName, TestName)                             \
159       : public CaseName<gtest_TypeParam_> {                                    \
160    private:                                                                    \
161     typedef CaseName<gtest_TypeParam_> TestFixture;                            \
162     typedef gtest_TypeParam_ TypeParam;                                        \
163     virtual void TestBody();                                                   \
164   };                                                                           \
165   bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ =   \
166       ::testing::internal::TypeParameterizedTest<                              \
167           CaseName,                                                            \
168           ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName,    \
169                                                                   TestName)>,  \
170           GTEST_TYPE_PARAMS_(CaseName)>::                                      \
171           Register(                                                            \
172               "", ::testing::internal::CodeLocation(__FILE__, __LINE__),       \
173               #CaseName,                                                       \
174               ::xla::PrependDisabledIfIndicated(#CaseName, #TestName).c_str(), \
175               0);                                                              \
176   template <typename gtest_TypeParam_>                                         \
177   void GTEST_TEST_CLASS_NAME_(CaseName,                                        \
178                               TestName)<gtest_TypeParam_>::TestBody()
179 
180 #endif  // TENSORFLOW_COMPILER_XLA_TESTS_TEST_MACROS_H_
181