From 5e9388d1700d6c588aa70bcd2378985e19da02dd Mon Sep 17 00:00:00 2001 From: John Stiles Date: Mon, 7 Mar 2022 17:54:21 -0500 Subject: [PATCH] Add support for conditional unit tests. DEF_CONDITIONAL_TEST and DEF_CONDITIONAL_GPUTEST_FOR_xxxx_CONTEXTS will allow unit tests to be considered or ignored based on a passed-in boolean condition. DEF_TEST_DISABLED is now implemented as a conditional test hard-coded with a "false" condition. This allows macros (such as SKSL_TEST) to add unit tests based on the result of a comparison. Change-Id: Ic5325569009cfce768ba8942907c1d3e7d69ca1c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/517516 Auto-Submit: John Stiles Reviewed-by: Brian Osman Commit-Queue: John Stiles --- tests/Test.h | 44 ++++++++++++++++++++++++++------------------ tests/TestTest.cpp | 34 ++++++++++++++++++++++++++++++++++ tools/Registry.h | 41 ++++++++++++++++++++++++----------------- 3 files changed, 84 insertions(+), 35 deletions(-) diff --git a/tests/Test.h b/tests/Test.h index 87b3372938..80e6dc41c9 100644 --- a/tests/Test.h +++ b/tests/Test.h @@ -99,7 +99,7 @@ struct Test { } }; -typedef sk_tools::Registry TestRegistry; +using TestRegistry = sk_tools::Registry; /* Use the following macros to make use of the skiatest classes, e.g. @@ -184,20 +184,15 @@ private: } \ } while (0) -#define DEF_TEST(name, reporter) \ - static void test_##name(skiatest::Reporter*, const GrContextOptions&); \ - skiatest::TestRegistry name##TestRegistry( \ - skiatest::Test(#name, /*gpu*/ false, /*graphite*/ false, test_##name)); \ +#define DEF_CONDITIONAL_TEST(name, reporter, condition) \ + static void test_##name(skiatest::Reporter*, const GrContextOptions&); \ + skiatest::TestRegistry name##TestRegistry( \ + skiatest::Test(#name, /*gpu=*/false, /*graphite=*/false, test_##name), condition); \ void test_##name(skiatest::Reporter* reporter, const GrContextOptions&) -#define DEF_TEST_DISABLED(name, reporter) \ - static void test_##name(skiatest::Reporter*, const GrContextOptions&); \ - skiatest::TestRegistry name##TestRegistry( \ - skiatest::Test(#name, /*gpu*/ false, /*graphite*/ false, test_##name)); \ - void test_##name(skiatest::Reporter* reporter, const GrContextOptions&) { \ - /* SkDebugf("Disabled:"#name "\n"); */ \ - } \ - void disabled_##name(skiatest::Reporter* reporter, const GrContextOptions&) +#define DEF_TEST(name, reporter) DEF_CONDITIONAL_TEST(name, reporter, true) + +#define DEF_TEST_DISABLED(name, reporter) DEF_CONDITIONAL_TEST(name, reporter, false) #ifdef SK_BUILD_FOR_UNIX #define UNIX_ONLY_TEST DEF_TEST @@ -212,7 +207,7 @@ private: test_##name(reporter); \ } \ skiatest::TestRegistry name##TestRegistry( \ - skiatest::Test(#name, /*gpu*/ false, /*graphite*/ true, test_graphite_##name)); \ + skiatest::Test(#name, /*gpu=*/false, /*graphite=*/true, test_graphite_##name)); \ void test_##name(skiatest::Reporter* reporter) #define DEF_GRAPHITE_TEST_FOR_CONTEXTS(name, reporter, graphite_context) \ @@ -222,26 +217,39 @@ private: skiatest::graphite::RunWithGraphiteTestContexts(test_##name, _reporter); \ } \ skiatest::TestRegistry name##TestRegistry( \ - skiatest::Test(#name, /*gpu*/ false, /*graphite*/ true, \ + skiatest::Test(#name, /*gpu=*/false, /*graphite=*/true, \ test_graphite_contexts_##name)); \ void test_##name(skiatest::Reporter* reporter, skgpu::Context* graphite_context) #define DEF_GPUTEST(name, reporter, options) \ static void test_##name(skiatest::Reporter*, const GrContextOptions&); \ skiatest::TestRegistry name##TestRegistry( \ - skiatest::Test(#name, /*gpu*/ true, /*graphite*/ false, test_##name)); \ + skiatest::Test(#name, /*gpu=*/true, /*graphite=*/false, test_##name)); \ void test_##name(skiatest::Reporter* reporter, const GrContextOptions& options) -#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info, options_filter) \ +#define DEF_CONDITIONAL_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info, \ + options_filter, condition) \ static void test_##name(skiatest::Reporter*, const sk_gpu_test::ContextInfo&); \ static void test_gpu_contexts_##name(skiatest::Reporter* reporter, \ const GrContextOptions& options) { \ skiatest::RunWithGPUTestContexts(test_##name, context_filter, reporter, options); \ } \ skiatest::TestRegistry name##TestRegistry( \ - skiatest::Test(#name, /*gpu*/ true, /*graphite*/ false, test_gpu_contexts_##name, options_filter)); \ + skiatest::Test(#name, /*gpu=*/true, /*graphite=*/false, test_gpu_contexts_##name, \ + options_filter), condition); \ void test_##name(skiatest::Reporter* reporter, const sk_gpu_test::ContextInfo& context_info) +#define DEF_CONDITIONAL_GPUTEST_FOR_ALL_CONTEXTS(name, reporter, context_info, condition) \ + DEF_CONDITIONAL_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info, nullptr, \ + condition) +#define DEF_CONDITIONAL_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info, condition) \ + DEF_CONDITIONAL_GPUTEST_FOR_CONTEXTS(name, \ + sk_gpu_test::GrContextFactory::IsRenderingContext, \ + reporter, context_info, nullptr, condition) + +#define DEF_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info, options_filter) \ + DEF_CONDITIONAL_GPUTEST_FOR_CONTEXTS(name, context_filter, reporter, context_info, \ + options_filter, true) #define DEF_GPUTEST_FOR_ALL_CONTEXTS(name, reporter, context_info) \ DEF_GPUTEST_FOR_CONTEXTS(name, nullptr, reporter, context_info, nullptr) diff --git a/tests/TestTest.cpp b/tests/TestTest.cpp index a68c60d853..226f0adbef 100644 --- a/tests/TestTest.cpp +++ b/tests/TestTest.cpp @@ -15,6 +15,16 @@ DEF_TEST(TestNormal, reporter) { REPORTER_ASSERT(reporter, reporter); } +// This is an example of a conditional test with a true condition. +DEF_CONDITIONAL_TEST(TestTrueCondition, reporter, 1 == 1) { + REPORTER_ASSERT(reporter, reporter); +} + +// This is an example of a conditional test with a false condition. +DEF_CONDITIONAL_TEST(TestFalseCondition, reporter, 1 == 0) { + ERRORF(reporter, "DEF_CONDITIONAL_TEST executed a test with a false condition"); +} + // This is an example of a GPU test that uses GrContextOptions to do the test. DEF_GPUTEST(TestGpuFactory, reporter, factory) { REPORTER_ASSERT(reporter, reporter); @@ -40,3 +50,27 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(TestMockContext, reporter, ctxInfo) { REPORTER_ASSERT(reporter, reporter); REPORTER_ASSERT(reporter, ctxInfo.directContext()); } + +// Conditional GPU tests will only execute if the provided condition parameter is true. +DEF_CONDITIONAL_GPUTEST_FOR_ALL_CONTEXTS(TestGpuAllContextsWithTrueCondition, + reporter, ctxInfo, true) { + REPORTER_ASSERT(reporter, reporter); + REPORTER_ASSERT(reporter, ctxInfo.directContext()); +} + +DEF_CONDITIONAL_GPUTEST_FOR_ALL_CONTEXTS(TestGpuAllContextsWithFalseCondition, + reporter, ctxInfo, false) { + ERRORF(reporter, "DEF_CONDITIONAL_GPUTEST_FOR_ALL_CONTEXTS ran with a false condition"); +} + +DEF_CONDITIONAL_GPUTEST_FOR_RENDERING_CONTEXTS(TestGpuRenderingContextsWithTrueCondition, + reporter, ctxInfo, true) { + REPORTER_ASSERT(reporter, reporter); + REPORTER_ASSERT(reporter, ctxInfo.directContext()); +} + +DEF_CONDITIONAL_GPUTEST_FOR_RENDERING_CONTEXTS(TestGpuRenderingContextsWithFalseCondition, + reporter, ctxInfo, false) { + ERRORF(reporter, "DEF_CONDITIONAL_GPUTEST_FOR_RENDERING_CONTEXTS ran with a false condition"); +} + diff --git a/tools/Registry.h b/tools/Registry.h index d5731a74bf..df72e3d57f 100644 --- a/tools/Registry.h +++ b/tools/Registry.h @@ -13,27 +13,17 @@ namespace sk_tools { -/** Template class that registers itself (in the constructor) into a linked-list - and provides a function-pointer. This can be used to auto-register a set of - services, e.g. a set of image codecs. +/** + * Template class that registers itself (in the constructor) into a linked-list + * and provides a function-pointer. This can be used to auto-register a set of + * services, e.g. a set of image codecs. */ template class Registry : SkNoncopyable { public: - explicit Registry(T value) : fValue(value) { -#ifdef SK_BUILD_FOR_ANDROID - // work-around for double-initialization bug - { - Registry* reg = gHead; - while (reg) { - if (reg == this) { - return; - } - reg = reg->fChain; - } + explicit Registry(T value, bool condition = true) : fValue(value) { + if (condition) { + this->linkToRegistryHead(); } -#endif - fChain = gHead; - gHead = this; } static const Registry* Head() { return gHead; } @@ -54,6 +44,23 @@ public: }; private: + void linkToRegistryHead() { +#ifdef SK_BUILD_FOR_ANDROID + // work-around for double-initialization bug + { + Registry* reg = gHead; + while (reg) { + if (reg == this) { + return; + } + reg = reg->fChain; + } + } +#endif + fChain = gHead; + gHead = this; + } + T fValue; Registry* fChain;