From: Efimov Alexander/AI Tools Lab/./Samsung Electronics Date: Tue, 10 Jul 2018 16:15:27 +0000 (+0300) Subject: Fix generator consistency checker (#559) X-Git-Tag: nncc_backup~2452 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d1c4e73be8eb0d476e934dff1cf079e1410fd766;p=platform%2Fcore%2Fml%2Fnnfw.git Fix generator consistency checker (#559) Fix generator consistency checker Fix argument checker in generator and add tests for it Signed-off-by: Efimov Alexander --- diff --git a/contrib/nnc/libs/backend/soft/CMakeLists.txt b/contrib/nnc/libs/backend/soft/CMakeLists.txt index 4ddad1f..67cf563 100644 --- a/contrib/nnc/libs/backend/soft/CMakeLists.txt +++ b/contrib/nnc/libs/backend/soft/CMakeLists.txt @@ -1,6 +1,13 @@ -file(GLOB_RECURSE LANG_BACKEND_SOURCES src/*.cpp) +file(GLOB_RECURSE SOFT_BACKEND_SOURCES src/*.cpp) +file(GLOB_RECURSE HEADERS "include/*.h") +file(GLOB_RECURSE TESTS "src/*.test.cpp") +list(REMOVE_ITEM SOFT_BACKEND_SOURCES ${TESTS}) -add_library(soft_backend SHARED ${LANG_BACKEND_SOURCES}) +add_library(soft_backend SHARED ${SOFT_BACKEND_SOURCES}) + +add_nncc_test(soft_backend_test ${TESTS}) +nncc_target_link_libraries(soft_backend_test nncc_core nnc_core nnc_plugin_core nncc_foundation soft_backend) +target_include_directories(soft_backend_test PUBLIC include) target_link_libraries(soft_backend PRIVATE nncc_core) diff --git a/contrib/nnc/libs/backend/soft/src/generator.cpp b/contrib/nnc/libs/backend/soft/src/generator.cpp index 2890d54..12dc0b0 100644 --- a/contrib/nnc/libs/backend/soft/src/generator.cpp +++ b/contrib/nnc/libs/backend/soft/src/generator.cpp @@ -36,7 +36,26 @@ bool fillFileStats(const string &path, struct stat &s) if (path.empty()) return false; if (stat(path.c_str(), &s)) - throw PluginException("Can not get info for file: " + path); + { + if (errno == ENOENT) + { + // file not found, try to create it + ofstream f(path); + if (!f.good()) + throw PluginException("Can not create output file: " + path); + // try again + int res = stat(path.c_str(), &s); + (void) res; + // on this step everythink should be fine, since we just created file + assert(!res); + return true; + } + else + throw PluginException("Can not get info for file: " + path); + } + // check that selected file is regular or char device(to accept /dev/null, and simular) + if (!(s.st_mode & (S_IFREG | S_IFCHR))) + throw PluginException("Not a regular file: " + path); return true; } @@ -53,13 +72,13 @@ void BaseCodeGenerator::checkCorrectness() // check that header, code and model file paths refers to different files. // Exception: stdout could be common output stream struct stat headerStat, codeStat, modelStat; - bool skipHeader = fillFileStats(_headerFile, headerStat); - bool skipCode = fillFileStats(_codeFile, codeStat); - bool skipModel = fillFileStats(_modelFile, modelStat); + bool checkHeader = fillFileStats(_headerFile, headerStat); + bool checkCode = fillFileStats(_codeFile, codeStat); + bool checkModel = fillFileStats(_modelFile, modelStat); - if ((!skipHeader && !skipCode && areFilesEqual(headerStat, codeStat)) || - (!skipHeader && !skipModel && areFilesEqual(headerStat, modelStat)) || - (!skipCode && !skipModel && areFilesEqual(codeStat, modelStat))) + if ((checkHeader && checkCode && areFilesEqual(headerStat, codeStat)) || + (checkHeader && checkModel && areFilesEqual(headerStat, modelStat)) || + (checkCode && checkModel && areFilesEqual(codeStat, modelStat))) { throw PluginException("output files should not be equal"); } diff --git a/contrib/nnc/libs/backend/soft/src/generator.test.cpp b/contrib/nnc/libs/backend/soft/src/generator.test.cpp new file mode 100644 index 0000000..ba5c546 --- /dev/null +++ b/contrib/nnc/libs/backend/soft/src/generator.test.cpp @@ -0,0 +1,95 @@ +#include "generator.h" +#include "PluginException.h" + +#include + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace nncc::contrib; +using namespace nncc::contrib::backend::soft; + +static bool isFileExists(const string &path) +{ + ifstream f(path); + return f.good(); +} + +static void createFile(const string &path) +{ + assert(!isFileExists(path)); + ofstream f(path); + assert(f.good()); + f << "hello world\n"; +} + +static void createDir(const string &path) +{ + int res = mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + assert(!res); +} + +static void deleteFile(const string &path) +{ + int res = remove(path.c_str()); + assert(!res && "failed to remove file"); +} + +static void deleteDir(const string &path) +{ + int res = rmdir(path.c_str()); + assert(!res && "failed to remove dir"); +} + +TEST(Generator, check_path_consistency) +{ + // assume here that c++ and c code generators behave identically in terms of parameters check + // test only c++ generator + const char *TEST_FILE1 = "test_file1"; + const char *TEST_FILE2 = "test_file2"; + const char *TEST_DIR = "test_dir"; + + // iterate this arrays to check that all arguments are working equally + const char *fileNames1[] = {"", "" , TEST_FILE1, "", ""}; + const char *fileNames2[] = {TEST_FILE1, TEST_FILE1, "", TEST_FILE1, TEST_FILE1}; + const char *fileNames3[] = {TEST_FILE1, TEST_FILE2, "", TEST_FILE1, TEST_FILE2}; + const char *dirNames[] = {"", "" , TEST_DIR, "", ""}; + + assert(!isFileExists(TEST_DIR) && "remove test_dir"); + assert(!isFileExists(TEST_FILE2) && "remove test_file2"); + createDir(TEST_DIR); + for (int i = 0; i < 3; ++i) + { + // check that test file is created + assert(!isFileExists(TEST_FILE1) && "remove test_file1"); + CPPCodeGenerator::create(fileNames1[i], fileNames1[i + 1], fileNames1[i + 2]); + ASSERT_TRUE(isFileExists(TEST_FILE1)); + // file already exists + struct stat s1; + int res = stat(TEST_FILE1, &s1); + assert(!res); + CPPCodeGenerator::create(fileNames1[i], fileNames1[i + 1], fileNames1[i + 2]); + struct stat s2; + res = stat(TEST_FILE1, &s2); + assert(!res); + deleteFile(TEST_FILE1); + // check that file is not changed at this point + ASSERT_EQ(s1.st_ino, s2.st_ino); + ASSERT_EQ(s1.st_size, s2.st_size); + // check that dir is not valid output + EXPECT_THROW(CPPCodeGenerator::create(dirNames[i], dirNames[i + 1], dirNames[i + 2]), PluginException); + // check that equal files are not permitted + EXPECT_THROW(CPPCodeGenerator::create(fileNames2[i], fileNames2[i + 1], fileNames2[i + 2]), PluginException); + // check that different files are ok + CPPCodeGenerator::create(fileNames3[i], fileNames3[i + 1], fileNames3[i + 2]); + deleteFile(TEST_FILE1); + } + deleteDir(TEST_DIR); + deleteFile(TEST_FILE2); +} +