#include #include /* defines FILENAME_MAX */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "CSlim/SlimUtil.h" #include "CSlim/SlimList.h" #include "CSlim/Fixtures.h" #include "CSlimTools.hh" //#include "PlotTools.hh" #include "TimeTable.hh" #include "AsciiReader.hh" #include "TimeTableCatalogFactory.hh" #include "TimeTableCatalogUtil.hh" #ifdef WINDOWS #include #define GetCurrentDir _getcwd #else #include #define GetCurrentDir getcwd #endif struct TestAmdaCommandLine; struct TestAmdaCommandLine { static TestAmdaCommandLine* getInstance() { if (!_currentInstance) { _currentInstance = new TestAmdaCommandLine; } return _currentInstance; } static void releaseInstance() { delete _currentInstance; _currentInstance = NULL; } static TestAmdaCommandLine* From(void *fixtureStorage) { return reinterpret_cast(fixtureStorage); } char _currentPath[FILENAME_MAX]; int _result; char* _stdOutFile; char* _stdErrFile; std::string _currentNameTest; int _indexTest; std::string _path; std::string _buildType; std::string _execPath; std::string _workingDirectory; private: TestAmdaCommandLine() : _result(0), _currentNameTest(""), _indexTest(0), _path(""), _buildType("Debug"), _execPath("../build/Debug/bin/"), _workingDirectory("app-debug") { const char* lBuildType = getenv("BUILD_TYPE"); if (lBuildType && (strcmp(lBuildType, "Release") == 0)) { _buildType = lBuildType; _execPath = "../build/Release/bin/"; _workingDirectory = "app-release"; } chdir(_workingDirectory.c_str()); GetCurrentDir(_currentPath, sizeof(_currentPath)); _stdOutFile = tmpnam(NULL); _stdErrFile = tmpnam(NULL); } ~TestAmdaCommandLine() { remove(_stdOutFile); remove(_stdErrFile); } static TestAmdaCommandLine* _currentInstance; }; TestAmdaCommandLine* TestAmdaCommandLine::_currentInstance = NULL; extern "C" { void* TestAmdaCommandLine_Create(StatementExecutor* /*errorHandler*/, SlimList* /*args*/) { return TestAmdaCommandLine::getInstance(); } void TestAmdaCommandLine_Destroy(void */*fixture*/) { // delete TestAmdaCommandLine::From(fixture); TestAmdaCommandLine::releaseInstance(); } static char* returnValueArgument(void *fixture, SlimList *args) { TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); bool valgrind = !access("valgrindMemCheck", R_OK); std::string commandExec = std::string(context->_currentPath) + "/" + context->_execPath + "/EXE_AMDA_Kernel "; if (valgrind) { mkdir("../build/report", S_IRWXU | S_IRGRP | S_IXGRP); std::string preCommande = std::string( "valgrind --xml=yes --xml-file=../build/report/reportValgrind_") + context->_currentNameTest + "_" + CSlimTools::intToString(context->_indexTest) + ".xml "; ++context->_indexTest; commandExec = preCommande + " " + std::string(context->_currentPath) + "/" + context->_execPath + "/EXE_AMDA_Kernel "; } // Set environment variable used to HIDE AMDA header // on produced files setenv ("HIDE_HEADER_FILE", "true", 1); std::string command = commandExec + SlimList_GetStringAt(args, 0); std::cout << "execute " << command << std::endl; int ret = system(command.c_str()); return CSlimTools::traitReturnSystem(ret); } static char* setPath(void *fixture, SlimList *args) { TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); context->_path = std::string(SlimList_GetStringAt(args, 0)); return CSlimTools::traitReturnSystem(0); } static char* commonExecute (void *fixture, SlimList *args) { TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); std::stringstream ss; // Set environment variable used to HIDE AMDA version number // on produced files setenv ("HIDE_VERSION", "true", 1); std::cerr << "Path: " << getenv("PATH") << std::endl; if (!access("valgrindMemCheck", R_OK)) { std::string cmd = std::string(SlimList_GetStringAt(args, 0)); boost::algorithm::trim(cmd); //Use valgrind only for AMDA executables std::vector allowedCmds{"amdaXMLRequestorTool", "amdaParameterGenerator", "amdaParameterInfo", "EXE_AMDA_Kernel", "ttConversion", "ttOperations"}; if (std::find(std::begin(allowedCmds), std::end(allowedCmds), cmd) != std::end(allowedCmds)) { mkdir("../build/report", S_IRWXU | S_IRGRP | S_IXGRP); ss << "valgrind --xml=yes --xml-file=../build/report/reportValgrind_" << context->_currentNameTest << "_" << CSlimTools::intToString(context->_indexTest) << ".xml "; ++context->_indexTest; } } ss << std::string(SlimList_GetStringAt(args, 0)) << " " << SlimList_GetStringAt(args, 1) << " > " << context->_stdOutFile << " 2> " << context->_stdErrFile; std::string newCommand = boost::replace_all_copy(ss.str(), "${OUTPUT}", context->_stdOutFile); std::cout << newCommand << std::endl; context->_result = system(newCommand.c_str()); //ss.str().c_str()); std::string command = std::string("cat ") + context->_stdErrFile; std::cerr << "display: " << system(command.c_str()) << std::endl; return CSlimTools::traitReturnSystem(context->_result); } static char* executeWithInfoCommandArgs(void *fixture, SlimList *args) { unsetenv ("HIDE_AMDA_DATE"); unsetenv ("HIDE_HEADER_FILE"); return commonExecute (fixture, args); } static char* executeCommandArgs(void *fixture, SlimList *args) { // Set environment variable used to HIDE AMDA creation date // on produced images setenv ("HIDE_AMDA_DATE", "true", 1); // Set environment variable used to HIDE AMDA header // on produced files setenv ("HIDE_HEADER_FILE", "true", 1); return commonExecute (fixture, args); } static char* result(void *fixture, SlimList */*args*/) { TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); return CSlimTools::traitReturnSystem(context->_result); } static char* logFilePattern(void */*fixture*/, SlimList *args) { std::string command = std::string("egrep '") + SlimList_GetStringAt(args, 0) + "' example.log"; int ret = system(command.c_str()); return CSlimTools::traitReturnSystem(ret); } static char* logFileBeforPattern(void */*fixture*/, SlimList *args) { std::string command = std::string("grep -m1 -B1000 \"") + SlimList_GetStringAt(args, 0) + "\" example.log"; command += std::string(" | egrep \"") + SlimList_GetStringAt(args, 1) + "\""; int ret = system(command.c_str()); return CSlimTools::traitReturnSystem(ret); } static char* errFilePattern(void *fixture, SlimList *args) { TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); std::string command = std::string("egrep '") + SlimList_GetStringAt(args, 0) + "' " + context->_stdErrFile; int ret = system(command.c_str()); return CSlimTools::traitReturnSystem(ret); } static char* checkTimeTableFileType(void */*fixture*/, SlimList *args) { int result = 0; // Check the result TimeTable file name std::string file(SlimList_GetStringAt(args, 0)); // Check the result TimeTable file name std::string fileType(SlimList_GetStringAt(args, 1)); // Check file existence if (access(file.c_str(), F_OK) != 0) { result = -3; } // Read Time Table reference std::string readerType = TimeTableCatalog::TimeTableCatalogFactory::getInstance().getReaderType(file); if(fileType != readerType) { result = -1; } static char returnStr[128]; sprintf (returnStr, "%d", result); return const_cast(returnStr); } static char* diffOutputFileRef(void *fixture, SlimList *args) { TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); std::string command = std::string("diff ") + context->_stdOutFile + " " + context->_path + SlimList_GetStringAt(args, 0); int ret = system(command.c_str()); return CSlimTools::traitReturnSystem(ret); } static char* diffOutputFileFile1File2(void *fixture, SlimList *args) { TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); std::string command = std::string("diff ") + context->_path + SlimList_GetStringAt(args, 0) + " " + SlimList_GetStringAt(args, 1); int ret = system(command.c_str()); return CSlimTools::traitReturnSystem(ret); // return CSlimTools::compareFile(SlimList_GetStringAt(args, 0), SlimList_GetStringAt(args, 1)); } static char *dodiffTimeTable(const char *tt1, const char *tt2) { std::stringstream str; std::ifstream fileLeft(tt1); std::ifstream fileRight(tt2); bool ret = true; if (fileLeft.good() && fileRight.good()) { int lineNumber = 0; double maxEpsilon = 0; while (fileLeft.good() && fileRight.good()) { std::string lineLeft; std::string lineRight; ++lineNumber; getline(fileLeft, lineLeft); getline(fileRight, lineRight); if (lineLeft.find("# Creation Date:") != std::string::npos && lineRight.find("# Creation Date:") != std::string::npos) { // ignore difference between creation date continue; } char *tmp = CSlimTools::compareLine(lineLeft, lineRight, 0, lineNumber, maxEpsilon); if ((tmp[0] != '0' || tmp[1] != '\0')) { str << "line " << lineNumber << ": " << tmp; ret = false; } } if (!(fileLeft.eof()) || !(fileRight.eof())) { std::cout << "line " << lineNumber << " nb lines different" << std::endl; str << "nb lines different"; ret = false; } } else { if (fileRight.good()) { std::cout << "file '" << tt1 << "' not found" << std::endl; str << std::string("file '") + tt1 + "' not found"; ret = false; } else { std::cout << "file '" << tt2 << "' not found" << std::endl; str << std::string("file '") + tt2 + "' not found"; ret = false; } } if (ret) { return const_cast("0"); } else { std::string error = str.str(); std::vector data(error.size() + 1); std::copy(error.begin(), error.end(), data.begin()); return &data[0]; } } /** * @brief Check if for a reference interval, there is a corresponding interval in the given result. * When checking two intervals, we take into account that it could be a delta (no more than sampling time) * between the two start time and/or stop time. * It's also possible that the two intervals are not at the same indices and so we have a window on which a search is done. */ static char* diffTimeTableInterTT1TT2(void */*fixture*/, SlimList *args) { //TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); // This must be the reference file. std::string file1(SlimList_GetStringAt(args, 0)); // This must be the result file. std::string file2(SlimList_GetStringAt(args, 1)); // Check file existence if (access(file1.c_str(), F_OK) != 0) { return const_cast("-3"); } if(access(file2.c_str(), F_OK) != 0) { return const_cast("-3"); } // Read Time Table reference std::string readerType = TimeTableCatalog::TimeTableCatalogFactory::getInstance().getReaderType(file1); TimeTableCatalog::TimeTable tt1; tt1.read(file1, readerType); // Read Time Table result readerType = TimeTableCatalog::TimeTableCatalogFactory::getInstance().getReaderType(file2); TimeTableCatalog::TimeTable tt2; tt2.read(file2, readerType); // Get sampling time and check it int samplingTime_1 = 1, samplingTime_2 = 2; size_t pos1; // Constant is taken from ParamOutputDataMining class. const std::string search_1 = "Sampling: "; if ( (pos1 = tt1._history.find(search_1)) != std::string::npos) { pos1 += search_1.length(); std::string sSamplingTime = tt1._history.substr(pos1, tt1._history.length() - 1); samplingTime_1 = atoi(sSamplingTime.c_str()); } if ( (pos1 = tt2._history.find(search_1)) != std::string::npos) { pos1 += search_1.length(); std::string sSamplingTime = tt2._history.substr(pos1, tt1._history.length() - 1); samplingTime_2 = atoi(sSamplingTime.c_str()); } if (samplingTime_1 != samplingTime_2) { std::cout<("-2"); } // Get intervals std::vectortt1Intervals = tt1.getIntervals(); std::vectortt2Intervals = tt2.getIntervals(); // Get intervals size int tt1IntNumber = tt1Intervals.size(); int tt2IntNumber = tt2Intervals.size(); // Default window is set to 10 int windowInterval = 10; // If intervals size are not the same we take difference length. if(tt1IntNumber != tt2IntNumber) { windowInterval = abs(tt1IntNumber - tt2IntNumber); } // Store index of result interval for which an interval is matching with reference interval. std::vector resultIndexUsed; int error = 0; // Try to find a similarity for each interval in the two file. for(int index = 0; index < tt1IntNumber; index++) { std::stringstream startTime1, startTime2, stopTime1, stopTime2; TimeTableCatalog::TimeInterval ttInterval_1 = tt1Intervals[index]; TimeTableCatalog::writeISOTime(ttInterval_1._startTime, TimeTableCatalog::TimeTable::TIME_FORMAT::YYYYMMDDThhmmss, startTime1); TimeTableCatalog::writeISOTime(ttInterval_1._stopTime, TimeTableCatalog::TimeTable::TIME_FORMAT::YYYYMMDDThhmmss, stopTime1); if (index >= tt2IntNumber) { error = -1; std::cout<<"No similarity found for this result interval: ["< tt1IntNumber - windowInterval) { endParssing = tt1IntNumber - index; } bool notFound = true; // Parse window index while ((parssingIndex <= endParssing) && notFound) { ttInterval_2 = tt2Intervals[index + parssingIndex]; if( (abs(ttInterval_1._startTime - ttInterval_2._startTime) < samplingTime_1) && (abs(ttInterval_1._stopTime - ttInterval_2._stopTime) < samplingTime_1) ) { notFound = false; resultIndexUsed.push_back(index + parssingIndex); } else { parssingIndex++; } } if(notFound) { error = -1; std::cout<<"No similarity found for this reference interval: ["<(returnStr); } static char* diffTimeTableTT1TT2(void *fixture, SlimList *args) { TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); std::string file1(SlimList_GetStringAt(args, 0)); std::string file2(SlimList_GetStringAt(args, 1)); // If there is no path "/" in the file name, so add path if(file1.find("/") == std::string::npos) { file1 = context->_path + file1; } if(file2.find("/") == std::string::npos) { file2 = context->_path + file2; } return dodiffTimeTable(file1.c_str(), file2.c_str()); } static char *diffOutputFiles(const char *file1, const char *file2, double epsilon) { std::cout << "Compare " << file1 << " to " << file2 << " with epsilon = " << epsilon << std::endl; return CSlimTools::compareFile(file1, file2, epsilon); } static char* diffOutputFileFile1File2Epsilon(void *fixture, SlimList *args) { TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); return diffOutputFiles( std::string(context->_path + SlimList_GetStringAt(args, 0)).c_str(), std::string(SlimList_GetStringAt(args, 1)).c_str(), SlimList_GetDoubleAt(args, 2)); } static char* diffOutputFileSameDirFile1File2Epsilon(void */*fixture*/, SlimList *args) { return diffOutputFiles(std::string(SlimList_GetStringAt(args, 0)).c_str(), std::string(SlimList_GetStringAt(args, 1)).c_str(), SlimList_GetDoubleAt(args, 2)); } static char* changeDirPath(void *fixture, SlimList *args) { TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); context->_result = chdir( std::string(SlimList_GetStringAt(args, 0)).c_str()); return CSlimTools::traitReturnSystem(context->_result); } static char* changeDirRestore(void *fixture, SlimList */*args*/) { TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); context->_result = chdir(context->_currentPath); return CSlimTools::traitReturnSystem(context->_result); } /** function used to log */ static char* referenceIdTest(void *fixture, SlimList *args) { std::cout << std::endl << "***************************************************************************" << std::endl; std::cout << "Test " << SlimList_GetStringAt(args, 0) << std::endl; std::cerr << "Test " << SlimList_GetStringAt(args, 0) << std::endl; TestAmdaCommandLine* context = TestAmdaCommandLine::From(fixture); const char *chaine = SlimList_GetStringAt(args, 0); std::stringstream ss; for (unsigned int it = 0; it < strlen(chaine); it++) { if (isalnum(chaine[it])) { ss << chaine[it]; } else { ss << "_"; } } context->_currentNameTest = ss.str(); return const_cast(""); } clock_t getExecutionTime(const std::string& name, std::vector args) { clock_t executionTime; if (name == "intersect") { std::vector tts; TimeTableCatalog::TimeTable tt1; tt1.read(args[0], TimeTableCatalog::AsciiReader::FORMAT); tts.push_back(tt1); std::cout << " " << tt1.getIntervalNumber() <<" intervals read" << std::endl; TimeTableCatalog::TimeTable tt2; tt2.read(args[1], TimeTableCatalog::AsciiReader::FORMAT); std::cout << " " << tt2.getIntervalNumber() <<" intervals read" << std::endl; tts.push_back(tt2); TimeTableCatalog::TimeTable tt; executionTime = clock(); std::unique_ptr intersectedTT = TimeTableCatalog::TimeTable::intersect(tts); executionTime = clock() - executionTime; std::cout << " " << intersectedTT->getIntervalNumber() <<" intervals generated" << std::endl; } printf("Execution time is %f seconds", ((float) executionTime) / CLOCKS_PER_SEC); return executionTime; } static char* calculateExecutionTime(void */*fixture*/, SlimList *args) { std::vector paths; std::istringstream iss(std::string(SlimList_GetStringAt(args, 1))); do { std::string ttpath; iss >> ttpath; paths.push_back(ttpath); } while (iss); std::string fname(SlimList_GetStringAt(args, 0)); std::string fargs(iss.str()); boost::algorithm::replace_all(fargs, " ", ","); printf("Executing %s (%s)...\n", fname.c_str(), fargs.c_str()); clock_t execTime = getExecutionTime(fname, paths); static char buf[256]; sprintf(buf, "%f", ((float) execTime) / CLOCKS_PER_SEC); return buf; } /** * @brief Check if calculated error rate is less than given error rate (maximum authorized error rate). */ //static char* calculateErrorRate(void */*fixture*/, SlimList *args) { /* std::string lReferenceFile(SlimList_GetStringAt(args, 0)); std::string lResultFile(SlimList_GetStringAt(args, 1)); double maxErrorRate = atof(SlimList_GetStringAt(args, 2)); // Check if file need to be converted in png format. if (lReferenceFile.find(".png") == std::string::npos) { lReferenceFile = PlotTools::convert2Png(lReferenceFile); } // Check if file need to be converted in png format. if (lResultFile.find(".png") == std::string::npos) { lResultFile = PlotTools::convert2Png(lResultFile); } std::cout<<"Reference file: "<("0"); } else { printf("Maximum error rate exceed (%f%%), current error rate is %f%%", maxErrorRate, errorRate); return const_cast("1"); } }*/ // Comparaison de deux images par production d'une image delta (ImgDiff static char* compareImg1Img2ImgDiff(void */*fixture*/, SlimList *args) { static char returnStr[128]; bool skip = !access("skipPlotCompare", R_OK); if (skip) { std::cout << "Skip plot compare" << std::endl; strcpy (returnStr, "0"); return (returnStr); } char command [2048]; sprintf (command, "compare %s %s %s", SlimList_GetStringAt(args, 0), SlimList_GetStringAt(args, 1), SlimList_GetStringAt(args, 2)); // Execute command int ret =system (command); if (ret == 0) strcpy (returnStr, "0"); else sprintf (returnStr, "Erreur systeme %d", ret); return (returnStr); } // Comparaison stricte de deux parties d'images static char* compareImg1Img2Extract(void */*fixture*/, SlimList *args) { static char returnStr[128]; bool skip = !access("skipPlotCompare", R_OK); if (skip) { std::cout << "Skip plot compare" << std::endl; strcpy (returnStr, "0"); return (returnStr); } char imgDiffFile[] = "/tmp/amdaImgDiff.XXXXXX"; close (mkstemp(imgDiffFile)); char imgDiffResultFile[] = "/tmp/amdaImgDiffResult.XXXXXX"; close (mkstemp(imgDiffResultFile)); char command [2048]; if (strcasecmp (SlimList_GetStringAt(args, 2), "all") != 0) { sprintf (command, "compare -extract %s -metric PSNR %s %s %s 2> %s", SlimList_GetStringAt(args, 2), SlimList_GetStringAt(args, 0), SlimList_GetStringAt(args, 1), imgDiffFile, imgDiffResultFile); } else { sprintf (command, "compare -metric PSNR %s %s %s 2> %s", SlimList_GetStringAt(args, 0), SlimList_GetStringAt(args, 1), imgDiffFile, imgDiffResultFile); } // Execute command and create imgDiffResultFile file int ret = system (command); if (ret == 0) { // Extract metric char metric [128]; memset (metric, 0, sizeof (metric)); FILE * fMetric = fopen (imgDiffResultFile, "r"); if (fMetric != NULL) { fgets (metric, sizeof(metric), fMetric); fclose (fMetric); if (strstr (metric, "inf") != NULL) strcpy (returnStr, "0"); else strcpy (returnStr, "Les images diffèrent"); } else { strcpy (returnStr, "Fichier metric non trouvé"); } } else { sprintf (returnStr, "Erreur systeme %d", ret); } // Remove temporary files unlink (imgDiffFile); unlink (imgDiffResultFile); return (returnStr); } SLIM_CREATE_FIXTURE(TestAmdaCommandLine) SLIM_FUNCTION(returnValueArgument) SLIM_FUNCTION(logFilePattern) SLIM_FUNCTION(logFileBeforPattern) SLIM_FUNCTION(changeDirPath) SLIM_FUNCTION(changeDirRestore) SLIM_FUNCTION(checkTimeTableFileType) SLIM_FUNCTION(diffTimeTableTT1TT2) SLIM_FUNCTION(diffTimeTableInterTT1TT2) SLIM_FUNCTION(diffOutputFileFile1File2) SLIM_FUNCTION(diffOutputFileFile1File2Epsilon) SLIM_FUNCTION(diffOutputFileSameDirFile1File2Epsilon) SLIM_FUNCTION(result) SLIM_FUNCTION(executeCommandArgs) SLIM_FUNCTION(executeWithInfoCommandArgs) SLIM_FUNCTION(errFilePattern) SLIM_FUNCTION(referenceIdTest) SLIM_FUNCTION(setPath) SLIM_FUNCTION(calculateExecutionTime) SLIM_FUNCTION(diffOutputFileRef) //SLIM_FUNCTION(calculateErrorRate) SLIM_FUNCTION(compareImg1Img2ImgDiff) SLIM_FUNCTION(compareImg1Img2Extract) SLIM_END }