From 3aaaf71b850a25a7216a29346ba6487804978bb3 Mon Sep 17 00:00:00 2001 From: Peter Goodman Date: Fri, 8 Dec 2017 23:58:59 -0500 Subject: [PATCH] Added support for c++ test fixtures. --- examples/CMakeLists.txt | 4 +++ examples/Fixture.cpp | 42 ++++++++++++++++++++++++++ src/include/deepstate/DeepState.hpp | 47 +++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 examples/Fixture.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d054a14..7573535 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -12,6 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. + +add_executable(Fixture Fixture.cpp) +target_link_libraries(Fixture deepstate) + add_executable(IntegerOverflow IntegerOverflow.cpp) target_link_libraries(IntegerOverflow deepstate) diff --git a/examples/Fixture.cpp b/examples/Fixture.cpp new file mode 100644 index 0000000..72a4e67 --- /dev/null +++ b/examples/Fixture.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 Trail of Bits, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +class MyTest : public deepstate::Test { + public: + + void SetUp(void) { + LOG(INFO) + << "Setting up!"; + } + + void TearDown(void) { + LOG(INFO) + << "Tearing down!"; + } + + deepstate::Symbolic x; +}; + +TEST_F(MyTest, Something) { + ASSUME_NE(x, 0); +} + +int main(void) { + return DeepState_Run(); +} + diff --git a/src/include/deepstate/DeepState.hpp b/src/include/deepstate/DeepState.hpp index 4a03dad..ef6541d 100644 --- a/src/include/deepstate/DeepState.hpp +++ b/src/include/deepstate/DeepState.hpp @@ -115,6 +115,21 @@ DEEPSTATE_INLINE static bool IsSymbolic(double x) { return DeepState_IsSymbolicDouble(x); } +// A test fixture. +class Test { + public: + Test(void) = default; + ~Test(void) = default; + inline void SetUp(void) {} + inline void TearDown(void) {} + + private: + Test(const Test &) = delete; + Test(Test &&) = delete; + Test &operator=(const Test &) = delete; + Test &operator=(Test &&) = delete; +}; + template class Symbolic { public: @@ -214,6 +229,38 @@ inline static void OneOf(FuncTys&&... funcs) { #define TEST(category, name) \ DeepState_EntryPoint(category ## _ ## name) +#define _TEST_F(fixture_name, test_name, file, line) \ + class fixture_name ## _ ## test_name : public fixture_name { \ + public: \ + void DoRunTest(void); \ + static void RunTest(void) { \ + do { \ + fixture_name ## _ ## test_name self; \ + self.SetUp(); \ + self.DoRunTest(); \ + self.TearDown(); \ + } while (false); \ + DeepState_Pass(); \ + } \ + static struct DeepState_TestInfo kTestInfo; \ + }; \ + struct DeepState_TestInfo fixture_name ## _ ## test_name::kTestInfo = { \ + nullptr, \ + fixture_name ## _ ## test_name::RunTest, \ + DEEPSTATE_TO_STR(fixture_name ## _ ## test_name), \ + file, \ + line, \ + }; \ + DEEPSTATE_INITIALIZER(DeepState_Register_ ## test_name) { \ + fixture_name ## _ ## test_name::kTestInfo.prev = DeepState_LastTestInfo; \ + DeepState_LastTestInfo = &(fixture_name ## _ ## test_name::kTestInfo); \ + } \ + void fixture_name ## _ ## test_name :: DoRunTest(void) + + +#define TEST_F(fixture_name, test_name) \ + _TEST_F(fixture_name, test_name, __FILE__, __LINE__) + #define LOG_DEBUG(cond) \ ::deepstate::Stream(DeepState_LogDebug, (cond), __FILE__, __LINE__)