int main(int argc, const char **argv) { int success = 0; if (argc > 1) { clang::tooling::CommonOptionsParser OptionsParser(argc, argv, OpOvLintCategory); OpOvApp app(Conf.getValue()); app.init(); success = app.execute(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); app.cleanUp(); } return success; }
// The test definition void TestRunnerVisitor::VisitTestDefinition(TestDefinition *TD) { TestResults results(mOrder); results.mColumnNames = mColumnNames; results.using_fork = !NoForkOpt.getValue(); string test_name = TestResults::getColumnString(TEST_NAME, TD); results.mTmpFileName = test_name + "-tmp.txt"; pid_t pid; if(NoForkOpt.getValue() == false) { #ifdef __MINGW32__ cout << "Warning: Running test in same address space as jcut" << endl; pid = 0; #else if(pipe(results.mPipe) == -1) throw JCUTException("Could not create pipes for communication with the test "+test_name); pid = fork(); #endif if(pid == -1) throw JCUTException("Could not fork process for test "+test_name); } else pid = 0; if(pid == 0) { // Child process will execute the test if(TD->hasTestMockup()) { vector<MockupFunction*> mockups= TD->getTestMockup()->getMockupFixture()->getMockupFunctions(); for(MockupFunction* m : mockups) { llvm::Function* change_to_mockup = m->getMockupFunction(); mEE->runFunction(change_to_mockup,mArgs); } } runFunction(TD); llvm::Function* func = TD->getLLVMResultFunction(); if(!func) assert(false && "Function test result not found!"); llvm::GenericValue ret = mEE->runFunction(func, mArgs); TD->setPassingValue(ret.IntVal.getBoolValue()); std::vector<ExpectedExpression*> failing; // @bug @todo Debug ExpectedExpressions: Try all possible combinations. // When the test does not have an expected result and the expected expression // should fail, it always passess. for(ExpectedExpression* ptr : mExpExpr) { llvm::Function* ee_func = ptr->getLLVMResultFunction(); if(!ee_func) assert(false && "Function expected result result not found!"); llvm::GenericValue ee_ret = mEE->runFunction(ee_func, mArgs); bool passed = ee_ret.IntVal.getBoolValue(); if(passed == false) failing.push_back(ptr); TD->setPassingValue(passed); } mExpExpr.clear(); // Do the opposite steps for the Mockups if(TD->hasTestMockup()) { vector<MockupFunction*> mockups = TD->getTestMockup()->getMockupFixture()->getMockupFunctions(); for(MockupFunction* m : mockups) { llvm::Function* change_to_original = m->getOriginalFunction(); mEE->runFunction(change_to_original,mArgs); } //////////////////////////////////////////////// // Point to the mockup functions for the current group executeMockupFunctionsOnTopOfStack(); } // Include failing ExpectedExpressions from before and after statements. if(!failing.empty()) TD->setFailedExpectedExpressions(failing); results.collectTestResults(TD); results.saveToDisk(); if(NoForkOpt.getValue() == false) #ifdef __MINGW32__ do {} while(0); // @todo implement fork in windows #else _Exit(EXIT_SUCCESS); #endif } // end of child process else { // Continue parent process #ifdef __MINGW32__ do {} while(0); // @todo implement fork in windows #else int status = 0; waitpid(pid, &status, 0); if(WIFEXITED(status)) { // Child process ended normally } else { stringstream ss; string function_called = TD->getTestFunction()-> getFunctionCall()->getFunctionCalledString(); ss << "The function " << function_called << " crashed during execution. More details:" << endl; ss << "I ran that function in a different process but it crashed. Please debug that function" << endl; if(WIFSIGNALED(status)) { ss << "Child process was terminated by signal: " << strsignal(status) << endl; if(WCOREDUMP(status)) ss << "Child process produced a core dump!" << endl; } throw JCUTException(ss.str()); } #endif } results.mResults = results.readFromDisk(); TD->setTestResults(results.mResults); }