halcc: Create directory for .hal-backend-compatibility if not exist 35/313135/1
authorYoungjae Cho <y0.cho@samsung.com>
Wed, 19 Jun 2024 07:08:07 +0000 (16:08 +0900)
committerYoungjae Cho <y0.cho@samsung.com>
Wed, 19 Jun 2024 08:00:34 +0000 (17:00 +0900)
Change-Id: I1ba61268f2ba5503ef85ef2c106d7bd5f456231d
Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
src/hal-api-compatibility-checker.c
tests/unittest/test-hal-compatibility-checker.cc

index 78746c5516ed7884b8b9353d8dd96dbcd31d7883..fe24be1e94d9029e99a27b481a39c9721ba3e026 100644 (file)
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 #include <stdbool.h>
 #include <errno.h>
 #include <assert.h>
 #include <fcntl.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <pwd.h>
 #include <grp.h>
@@ -280,12 +282,67 @@ static bool is_system_generator_context(void)
        return true;
 }
 
+static int mkdir_one(const char *dir, mode_t mode)
+{
+       if (!dir)
+               return -EINVAL;
+
+       if (access(dir, F_OK) == 0)
+               return 0;
+
+       return mkdir(dir, mode);
+}
+
+static int create_directory(const char *path)
+{
+       char directory_path[PATH_MAX] = { 0 , };
+       char *p;
+       int ret;
+
+       if (!path)
+               return -EINVAL;
+
+       if (path[0] != '/')
+               return -EINVAL;
+
+       if (strlen(path) > PATH_MAX - 1)
+               return -ENAMETOOLONG;
+
+       // copy path except the last filename
+       strncpy(directory_path, path, strrchr(path, '/') - path);
+
+       p = strchr(directory_path + 1, '/');
+       for (;;) {
+               if (!p)
+                       break;
+
+               *p = '\0';
+               ret = mkdir_one(directory_path, 0644);
+               if (ret < 0)
+                       return ret;
+               *p = '/';
+
+               p = strchr(p + 1, '/');
+       }
+
+       return mkdir_one(directory_path, 0644);
+
+}
+
 static int write_comaptibility_info(struct compatibility_info *info, int entry_size)
 {
        int fd = -1;
        int ret;
        ssize_t n_write;
 
+       ret = create_directory(compatibility_result_path);
+       if (ret < 0) {
+               errno = -ret;
+               _E("Failed to create directory for %s, %m",
+                       compatibility_result_path);
+               return ret;
+       }
+
        fd = open(compatibility_result_path,
                O_WRONLY | O_CREAT | O_EXCL, 0644);
        if (fd == -1) {
@@ -382,9 +439,7 @@ static int load_module_compatibility_info_fallback(enum hal_module module,
        if (skip_version_check)
                return 0;
 
-       write_comaptibility_info(infos, HAL_MODULE_END);
-
-       return 0;
+       return write_comaptibility_info(infos, HAL_MODULE_END);
 }
 
 int hal_api_cc_check_backend_compatibility(enum hal_module module,
index 139292b723691f5a9d6c019a2fbc0cc8ec85225b..5b1310aac04ed6f16ac9ca317aee7b930929f9d2 100644 (file)
 
 using namespace std;
 
-#define TEST_COMPATIBILITY_RESULT_PATH "./compatibility-result"
-
 class HalccObjectTest : public ::testing::Test
 {
        protected:
                static void SetUpTestSuite() {
                        int ret;
-                       char cwd[PATH_MAX] = { 0, };
 
-                       ret = asprintf(&g_manifest_directory, "%s/%s",
-                               getcwd(cwd, sizeof(cwd)), "test-hal-manifest");
+                       g_cwd = getcwd(NULL, 0);
+                       if (!g_cwd)
+                               FAIL();
+
+                       ret = asprintf(&g_manifest_directory, "%s/%s", g_cwd, "test-hal-manifest");
+                       if (ret == -1)
+                               FAIL();
+
+                       ret = asprintf(&g_compatibility_result_path, "%s/.hal-backend-compatibility", g_cwd);
                        if (ret == -1)
                                FAIL();
 
@@ -55,9 +59,11 @@ class HalccObjectTest : public ::testing::Test
                static void TearDownTestSuite() {
                        for (int module = HAL_MODULE_UNKNOWN; module < HAL_MODULE_END; ++module)
                                mock_hal_backend_data_unset_version((enum hal_module) module);
-                       unlink(TEST_COMPATIBILITY_RESULT_PATH);
+                       unlink(g_compatibility_result_path);
                        unset_compatibility_manifest_directory();
+                       free(g_compatibility_result_path);
                        free(g_manifest_directory);
+                       free(g_cwd);
                        g_manifest_directory = NULL;
                }
 
@@ -71,10 +77,14 @@ class HalccObjectTest : public ::testing::Test
 
                static halcc_manifest *g_manifest;
                static char *g_manifest_directory;
+               static char *g_compatibility_result_path;
+               static char *g_cwd;
 };
 
 halcc_manifest* HalccObjectTest::g_manifest = NULL;
 char* HalccObjectTest::g_manifest_directory = NULL;
+char* HalccObjectTest::g_compatibility_result_path = NULL;
+char* HalccObjectTest::g_cwd = NULL;
 
 static bool have_exact_version(halcc_hal *hal, const char *version)
 {
@@ -215,15 +225,15 @@ TEST_F(HalccObjectTest, hal_create_result_file_success)
 
        /* mock systemd generator context */
        setenv("SYSTEMD_SCOPE", "system", 1);
-       set_compatibility_result_path(TEST_COMPATIBILITY_RESULT_PATH);
+       set_compatibility_result_path(g_compatibility_result_path);
 
        ret = hal_api_cc_check_backend_compatibility(HAL_MODULE_DEVICE_DISPLAY, &compatibility);
        ASSERT_EQ(ret, 0);
 
-       ret = access(TEST_COMPATIBILITY_RESULT_PATH, F_OK | ACCESS_DO_NOT_HOOK);
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
        ASSERT_EQ(ret, 0);
 
-       unlink(TEST_COMPATIBILITY_RESULT_PATH);
+       unlink(g_compatibility_result_path);
        unset_compatibility_result_path();
        unsetenv("SYSTEMD_SCOPE");
 }
@@ -233,12 +243,12 @@ TEST_F(HalccObjectTest, hal_create_result_file_fail)
        enum hal_common_backend_compatibility compatibility;
        int ret;
 
-       set_compatibility_result_path(TEST_COMPATIBILITY_RESULT_PATH);
+       set_compatibility_result_path(g_compatibility_result_path);
 
        ret = hal_api_cc_check_backend_compatibility(HAL_MODULE_DEVICE_DISPLAY, &compatibility);
        ASSERT_EQ(ret, 0);
 
-       ret = access(TEST_COMPATIBILITY_RESULT_PATH, F_OK | ACCESS_DO_NOT_HOOK);
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
        ASSERT_EQ(ret, -1);
 
        unset_compatibility_result_path();
@@ -250,9 +260,9 @@ TEST_F(HalccObjectTest, hal_check_compatibility_on_generator_context)
        int ret;
 
        setenv("SYSTEMD_SCOPE", "system", 1);
-       set_compatibility_result_path(TEST_COMPATIBILITY_RESULT_PATH);
+       set_compatibility_result_path(g_compatibility_result_path);
 
-       ret = access(TEST_COMPATIBILITY_RESULT_PATH, F_OK | ACCESS_DO_NOT_HOOK);
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
        ASSERT_EQ(ret, -1);
 
        mock_hal_backend_data_set_version(HAL_MODULE_DEVICE_DISPLAY, 1, 0); /* compatible with 1.2 */
@@ -262,7 +272,7 @@ TEST_F(HalccObjectTest, hal_check_compatibility_on_generator_context)
        ASSERT_EQ(ret, 0);
        ASSERT_EQ(compatibility, HAL_COMMON_BACKEND_COMPATIBILITY_COMPATIBLE);
 
-       ret = access(TEST_COMPATIBILITY_RESULT_PATH, F_OK | ACCESS_DO_NOT_HOOK);
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
        ASSERT_EQ(ret, 0);
 
        ret = hal_api_cc_check_backend_compatibility(HAL_MODULE_TDM, &compatibility);
@@ -272,7 +282,7 @@ TEST_F(HalccObjectTest, hal_check_compatibility_on_generator_context)
        mock_hal_backend_data_unset_version(HAL_MODULE_DEVICE_DISPLAY);
        mock_hal_backend_data_unset_version(HAL_MODULE_TDM);
 
-       unlink(TEST_COMPATIBILITY_RESULT_PATH);
+       unlink(g_compatibility_result_path);
        unset_compatibility_result_path();
        unsetenv("SYSTEMD_SCOPE");
 }
@@ -291,9 +301,9 @@ TEST_F(HalccObjectTest, hal_check_compatibility_not_on_generator_context)
        enum hal_common_backend_compatibility compatibility;
        int ret;
 
-       set_compatibility_result_path(TEST_COMPATIBILITY_RESULT_PATH);
+       set_compatibility_result_path(g_compatibility_result_path);
 
-       ret = access(TEST_COMPATIBILITY_RESULT_PATH, F_OK | ACCESS_DO_NOT_HOOK);
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
        ASSERT_EQ(ret, -1);
 
        mock_hal_backend_data_set_version(HAL_MODULE_DEVICE_DISPLAY, 1, 1);
@@ -361,7 +371,7 @@ TEST_F(HalccObjectTest, hal_check_compatibility_not_on_generator_context)
        ASSERT_EQ(ret, 0);
        ASSERT_EQ(compatibility, HAL_COMMON_BACKEND_COMPATIBILITY_INCOMPATIBLE);
 
-       ret = access(TEST_COMPATIBILITY_RESULT_PATH, F_OK | ACCESS_DO_NOT_HOOK);
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
        ASSERT_EQ(ret, -1);
 
        mock_hal_backend_data_unset_version(HAL_MODULE_DEVICE_DISPLAY);
@@ -374,9 +384,9 @@ TEST_F(HalccObjectTest, hal_get_backend_without_generator_without_result_file)
        int ret;
        void *funcs;
 
-       set_compatibility_result_path(TEST_COMPATIBILITY_RESULT_PATH);
+       set_compatibility_result_path(g_compatibility_result_path);
 
-       ret = access(TEST_COMPATIBILITY_RESULT_PATH, F_OK | ACCESS_DO_NOT_HOOK);
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
        ASSERT_EQ(ret, -1);
 
        funcs = malloc(10000);
@@ -386,7 +396,7 @@ TEST_F(HalccObjectTest, hal_get_backend_without_generator_without_result_file)
        ret = hal_common_get_backend(HAL_MODULE_DEVICE_DISPLAY, (void **) funcs);
        ASSERT_EQ(ret, 0);
 
-       ret = access(TEST_COMPATIBILITY_RESULT_PATH, F_OK | ACCESS_DO_NOT_HOOK);
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
        ASSERT_EQ(ret, -1);
 
        free(funcs);
@@ -402,9 +412,9 @@ TEST_F(HalccObjectTest, hal_get_backend_with_generator_without_result_file)
        void *funcs;
 
        setenv("SYSTEMD_SCOPE", "system", 1);
-       set_compatibility_result_path(TEST_COMPATIBILITY_RESULT_PATH);
+       set_compatibility_result_path(g_compatibility_result_path);
 
-       ret = access(TEST_COMPATIBILITY_RESULT_PATH, F_OK | ACCESS_DO_NOT_HOOK);
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
        ASSERT_EQ(ret, -1);
 
        funcs = malloc(10000);
@@ -414,7 +424,7 @@ TEST_F(HalccObjectTest, hal_get_backend_with_generator_without_result_file)
        ret = hal_common_get_backend(HAL_MODULE_DEVICE_DISPLAY, (void **) funcs);
        ASSERT_EQ(ret, 0);
 
-       ret = access(TEST_COMPATIBILITY_RESULT_PATH, F_OK | ACCESS_DO_NOT_HOOK);
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
        ASSERT_EQ(ret, -1);
 
        /**
@@ -427,7 +437,7 @@ TEST_F(HalccObjectTest, hal_get_backend_with_generator_without_result_file)
         * ASSERT_EQ(ret, -EINVAL);
         */
 
-       ret = access(TEST_COMPATIBILITY_RESULT_PATH, F_OK | ACCESS_DO_NOT_HOOK);
+       ret = access(g_compatibility_result_path, F_OK | ACCESS_DO_NOT_HOOK);
        ASSERT_EQ(ret, -1);
 
        free(funcs);