Skip to content

Commit

Permalink
Integrates phasar testing into cmake
Browse files Browse the repository at this point in the history
Adds extra cmake target check-phasar-unittests, for running all
unittests. Refactors tests access to test ll files and extracts direct
config usage, making config values easier exchangeable for testing.
  • Loading branch information
vulder committed Jun 17, 2020
1 parent 90de020 commit e8f82ea
Show file tree
Hide file tree
Showing 28 changed files with 339 additions and 292 deletions.
2 changes: 2 additions & 0 deletions cmake/phasar_macros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ function(add_phasar_unittest test_name)
add_executable(${test}
${test_name}
)
add_dependencies(PhasarUnitTests ${test})

if(USE_LLVM_FAT_LIB)
llvm_config(${test} USE_SHARED ${LLVM_LINK_COMPONENTS})
Expand Down Expand Up @@ -40,6 +41,7 @@ function(add_phasar_unittest test_name)

add_test(NAME "${test}"
COMMAND ${test} ${CATCH_TEST_FILTER}
WORKING_DIRECTORY ${PHASAR_UNITTEST_DIR}
)
set_tests_properties("${test}" PROPERTIES LABELS "all")
set(CTEST_OUTPUT_ON_FAILURE ON)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#include "llvm/Support/raw_ostream.h"

#include "phasar/Config/Configuration.h"
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/EdgeFunctions.h"
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/FlowEdgeFunctionCache.h"
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/FlowFunctions.h"
Expand Down Expand Up @@ -1618,15 +1619,17 @@ class IDESolver
public:
void enableESGAsDot() { SolverConfig.setEmitESG(); }

void emitESGAsDot(std::ostream &OS = std::cout) {
void
emitESGAsDot(std::ostream &OS = std::cout,
std::string DotConfigDir = PhasarConfig::PhasarDirectory()) {
LOG_IF_ENABLE(BOOST_LOG_SEV(lg::get(), DEBUG)
<< "Emit Exploded super-graph (ESG) as DOT graph";
BOOST_LOG_SEV(lg::get(), DEBUG)
<< "Process intra-procedural path egdes";
BOOST_LOG_SEV(lg::get(), DEBUG)
<< "=============================================");
DOTGraph<d_t> G;
DOTConfig::importDOTConfig();
DOTConfig::importDOTConfig(std::move(DotConfigDir));
DOTFunctionSubGraph *FG = nullptr;

// Sort intra-procedural path edges
Expand Down
4 changes: 3 additions & 1 deletion include/phasar/PhasarLLVM/Utils/DOTGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <set>
#include <string>

#include "phasar/Config/Configuration.h"
#include "phasar/Utils/Utilities.h"

namespace psr {
Expand All @@ -41,7 +42,8 @@ class DOTConfig {
static const std::string LambdaIDEdgeAttr() { return LambdaIDEdge; }
static const std::string LambdaInterEdgeAttr() { return LambdaInterEdge; }

static void importDOTConfig();
static void
importDOTConfig(std::string ConfigPath = PhasarConfig::PhasarDirectory());

static DOTConfig &getDOTConfig();
~DOTConfig() = default;
Expand Down
5 changes: 2 additions & 3 deletions lib/PhasarLLVM/Utils/DOTGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

#include "nlohmann/json.hpp"

#include "phasar/Config/Configuration.h"
#include "phasar/PhasarLLVM/Utils/DOTGraph.h"

namespace psr {
Expand Down Expand Up @@ -247,8 +246,8 @@ DOTConfig &DOTConfig::getDOTConfig() {
return DC;
}

void DOTConfig::importDOTConfig() {
boost::filesystem::path FilePath(PhasarConfig::PhasarDirectory());
void DOTConfig::importDOTConfig(std::string ConfigPath) {
boost::filesystem::path FilePath(ConfigPath);
FilePath /= boost::filesystem::path("config/DOTGraphConfig.json");
if (boost::filesystem::exists(FilePath) &&
!boost::filesystem::is_directory(FilePath)) {
Expand Down
26 changes: 23 additions & 3 deletions unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
add_custom_target(UnitTests)
set_target_properties(UnitTests PROPERTIES FOLDER "Tests")
add_dependencies(UnitTests LLFileGeneration)
add_custom_target(PhasarUnitTests)
set_target_properties(PhasarUnitTests PROPERTIES FOLDER "Unittests")
add_dependencies(PhasarUnitTests LLFileGeneration)

set(PHASAR_UNITTEST_DIR ${CMAKE_CURRENT_BINARY_DIR})

add_custom_target(check-phasar-unittests
COMMAND ${CMAKE_CTEST_COMMAND} --progress --output-on-failure -j 8
WORKING_DIRECTORY ${PHASAR_UNITTEST_DIR}
DEPENDS PhasarUnitTests
)

# Provide config files for unit tests
file(MAKE_DIRECTORY ${PHASAR_UNITTEST_DIR}/config/)
set(PHASAR_CONFIG_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../config/")
function(test_require_config_file file_name)
configure_file("${PHASAR_CONFIG_DIR}${file_name}"
"${PHASAR_UNITTEST_DIR}/config/."
COPYONLY
)
endfunction()

include_directories(TestUtils)

add_subdirectory(Config)
add_subdirectory(Controller)
Expand Down
34 changes: 17 additions & 17 deletions unittests/PhasarLLVM/ControlFlow/LLVMBasedBackwardCFGTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,15 @@
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedBackwardCFG.h"
#include "phasar/Utils/LLVMShorthands.h"

#include "TestConfig.h"

using namespace std;
using namespace psr;

class LLVMBasedBackwardCFGTest : public ::testing::Test {
protected:
const std::string PathToLlFiles =
PhasarConfig::getPhasarConfig().PhasarDirectory() +
"build/test/llvm_test_code/";
};

TEST_F(LLVMBasedBackwardCFGTest, BranchTargetTest) {
TEST(LLVMBasedBackwardCFGTest, BranchTargetTest) {
LLVMBasedBackwardCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/branch_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/branch_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");
const auto *Term = getNthTermInstruction(F, 1);
const auto *A = getNthInstruction(F, 10);
Expand All @@ -33,9 +29,10 @@ TEST_F(LLVMBasedBackwardCFGTest, BranchTargetTest) {
ASSERT_FALSE(Cfg.isBranchTarget(C, Term));
}

TEST_F(LLVMBasedBackwardCFGTest, HandlesMulitplePredeccessors) {
TEST(LLVMBasedBackwardCFGTest, HandlesMulitplePredeccessors) {
LLVMBasedBackwardCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/branch_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/branch_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");

// HANDLING CONDITIONAL BRANCH
Expand All @@ -59,9 +56,10 @@ TEST_F(LLVMBasedBackwardCFGTest, HandlesMulitplePredeccessors) {
ASSERT_EQ(PredsOfBrInst, Predeccessors);
}

TEST_F(LLVMBasedBackwardCFGTest, HandlesSingleOrEmptyPredeccessor) {
TEST(LLVMBasedBackwardCFGTest, HandlesSingleOrEmptyPredeccessor) {
LLVMBasedBackwardCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/function_call_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/function_call_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");

// HANDLING SINGLE PREDECCESSOR
Expand All @@ -81,9 +79,10 @@ TEST_F(LLVMBasedBackwardCFGTest, HandlesSingleOrEmptyPredeccessor) {
ASSERT_EQ(PredsOfTermInst, Predeccessor);
}

TEST_F(LLVMBasedBackwardCFGTest, HandlesMultipleSuccessors) {
TEST(LLVMBasedBackwardCFGTest, HandlesMultipleSuccessors) {
LLVMBasedBackwardCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/branch_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/branch_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");

// ret i32 0
Expand All @@ -98,9 +97,10 @@ TEST_F(LLVMBasedBackwardCFGTest, HandlesMultipleSuccessors) {
ASSERT_EQ(SuccsOfTermInst, Successor);
}

TEST_F(LLVMBasedBackwardCFGTest, HandlesSingleOrEmptySuccessor) {
TEST(LLVMBasedBackwardCFGTest, HandlesSingleOrEmptySuccessor) {
LLVMBasedBackwardCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/branch_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/branch_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");

// HANDLING SINGLE SUCCESSOR
Expand Down
60 changes: 31 additions & 29 deletions unittests/PhasarLLVM/ControlFlow/LLVMBasedCFGTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,15 @@
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"

#include "TestConfig.h"

using namespace std;
using namespace psr;

class LLVMBasedCFGTest : public ::testing::Test {
protected:
const std::string PathToLlFiles =
PhasarConfig::getPhasarConfig().PhasarDirectory() +
"build/test/llvm_test_code/";
};

TEST_F(LLVMBasedCFGTest, FallThroughSuccTest) {
TEST(LLVMBasedCFGTest, FallThroughSuccTest) {
LLVMBasedCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/branch_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/branch_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");

// HANDLING CONDITIONAL BRANCH
Expand All @@ -40,9 +36,10 @@ TEST_F(LLVMBasedCFGTest, FallThroughSuccTest) {
Cfg.isFallThroughSuccessor(BranchInst, getNthTermInstruction(F, 4)));
}

TEST_F(LLVMBasedCFGTest, BranchTargetTest) {
TEST(LLVMBasedCFGTest, BranchTargetTest) {
LLVMBasedCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/switch_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/switch_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");

// HANDLING SWITCH INSTRUCTION
Expand Down Expand Up @@ -75,9 +72,10 @@ TEST_F(LLVMBasedCFGTest, BranchTargetTest) {
ASSERT_TRUE(Cfg.isBranchTarget(BranchInst, getNthTermInstruction(F, 6)));
}

TEST_F(LLVMBasedCFGTest, HandlesMulitplePredeccessors) {
TEST(LLVMBasedCFGTest, HandlesMulitplePredeccessors) {
LLVMBasedCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/branch_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/branch_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");

// ret i32 0
Expand All @@ -91,9 +89,10 @@ TEST_F(LLVMBasedCFGTest, HandlesMulitplePredeccessors) {
ASSERT_EQ(PredsOfTermInst, Predeccessor);
}

TEST_F(LLVMBasedCFGTest, HandlesSingleOrEmptyPredeccessor) {
TEST(LLVMBasedCFGTest, HandlesSingleOrEmptyPredeccessor) {
LLVMBasedCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/branch_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/branch_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");

// HANDLING SINGLE PREDECCESSOR
Expand Down Expand Up @@ -122,9 +121,10 @@ TEST_F(LLVMBasedCFGTest, HandlesSingleOrEmptyPredeccessor) {
ASSERT_EQ(PredsOfInst, Predeccessor);
}

TEST_F(LLVMBasedCFGTest, HandlesMultipleSuccessors) {
TEST(LLVMBasedCFGTest, HandlesMultipleSuccessors) {
LLVMBasedCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/branch_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/branch_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");

// HANDLING CONDITIONAL BRANCH
Expand All @@ -148,9 +148,10 @@ TEST_F(LLVMBasedCFGTest, HandlesMultipleSuccessors) {
ASSERT_EQ(SuccsOfBrInst, Successors);
}

TEST_F(LLVMBasedCFGTest, HandlesSingleOrEmptySuccessor) {
TEST(LLVMBasedCFGTest, HandlesSingleOrEmptySuccessor) {
LLVMBasedCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/function_call_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/function_call_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");

// HANDLING SINGLE SUCCESSOR
Expand All @@ -170,9 +171,10 @@ TEST_F(LLVMBasedCFGTest, HandlesSingleOrEmptySuccessor) {
ASSERT_EQ(SuccsOfTermInst, Successors);
}

TEST_F(LLVMBasedCFGTest, HandlesCallSuccessor) {
TEST(LLVMBasedCFGTest, HandlesCallSuccessor) {
LLVMBasedCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "control_flow/function_call_cpp.ll"});
ProjectIRDB IRDB(
{unittest::PathToLLTestFiles + "control_flow/function_call_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");

// HANDLING CALL INSTRUCTION SUCCESSOR
Expand All @@ -185,29 +187,29 @@ TEST_F(LLVMBasedCFGTest, HandlesCallSuccessor) {
ASSERT_EQ(SuccsOfCallInst, Successors);
}

TEST_F(LLVMBasedCFGTest, HandleFieldLoadsArray) {
TEST(LLVMBasedCFGTest, HandleFieldLoadsArray) {
LLVMBasedCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "fields/array_1_cpp.ll"});
ProjectIRDB IRDB({unittest::PathToLLTestFiles + "fields/array_1_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");
const auto *Inst = getNthInstruction(F, 1);
ASSERT_FALSE(Cfg.isFieldLoad(Inst));
Inst = getNthInstruction(F, 6);
ASSERT_TRUE(Cfg.isFieldLoad(Inst));
}

TEST_F(LLVMBasedCFGTest, HandleFieldStoreArray) {
TEST(LLVMBasedCFGTest, HandleFieldStoreArray) {
LLVMBasedCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "fields/array_1_cpp.ll"});
ProjectIRDB IRDB({unittest::PathToLLTestFiles + "fields/array_1_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");
const auto *Inst = getNthInstruction(F, 1);
ASSERT_FALSE(Cfg.isFieldStore(Inst));
Inst = getNthInstruction(F, 9);
ASSERT_TRUE(Cfg.isFieldStore(Inst));
}

TEST_F(LLVMBasedCFGTest, HandleFieldLoadsField) {
TEST(LLVMBasedCFGTest, HandleFieldLoadsField) {
LLVMBasedCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "fields/field_1_cpp.ll"});
ProjectIRDB IRDB({unittest::PathToLLTestFiles + "fields/field_1_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");
const auto *Inst = getNthInstruction(F, 1);
ASSERT_FALSE(Cfg.isFieldLoad(Inst));
Expand All @@ -219,9 +221,9 @@ TEST_F(LLVMBasedCFGTest, HandleFieldLoadsField) {
ASSERT_TRUE(Cfg.isFieldLoad(Inst));
}

TEST_F(LLVMBasedCFGTest, HandleFieldStoreField) {
TEST(LLVMBasedCFGTest, HandleFieldStoreField) {
LLVMBasedCFG Cfg;
ProjectIRDB IRDB({PathToLlFiles + "fields/field_1_cpp.ll"});
ProjectIRDB IRDB({unittest::PathToLLTestFiles + "fields/field_1_cpp.ll"});
const auto *F = IRDB.getFunctionDefinition("main");
const auto *Inst = getNthInstruction(F, 1);
ASSERT_FALSE(Cfg.isFieldStore(Inst));
Expand Down
Loading

0 comments on commit e8f82ea

Please sign in to comment.