This is an automated email from the ASF dual-hosted git repository.

pengzheng pushed a commit to branch feature/refactor_bundle_cache
in repository https://gitbox.apache.org/repos/asf/celix.git


The following commit(s) were added to refs/heads/feature/refactor_bundle_cache 
by this push:
     new e9734f22 Test celix_utils_createDirectory thoroughly.
     new 27a5bbbe Merge remote-tracking branch 
'apache/feature/refactor_bundle_cache' into feature/refactor_bundle_cache
e9734f22 is described below

commit e9734f22b96bd7d2c3dfbfefb2ee634a0f7fc1dd
Author: PengZheng <[email protected]>
AuthorDate: Fri Mar 31 19:36:22 2023 +0800

    Test celix_utils_createDirectory thoroughly.
---
 libs/error_injector/CMakeLists.txt                 |  1 +
 libs/error_injector/stat/CMakeLists.txt            | 27 ++++++++++++
 libs/error_injector/stat/include/stat_ei.h         | 37 ++++++++++++++++
 libs/error_injector/stat/src/stat_ei.cc            | 43 +++++++++++++++++++
 libs/utils/gtest/CMakeLists.txt                    |  2 +-
 .../gtest/src/FileUtilsErrorInjectionTestSuite.cc  | 50 +++++++++++++++++++---
 libs/utils/gtest/src/FileUtilsTestSuite.cc         |  1 -
 libs/utils/src/celix_file_utils.c                  | 12 ++++--
 8 files changed, 161 insertions(+), 12 deletions(-)

diff --git a/libs/error_injector/CMakeLists.txt 
b/libs/error_injector/CMakeLists.txt
index 3479fe4d..193873cb 100644
--- a/libs/error_injector/CMakeLists.txt
+++ b/libs/error_injector/CMakeLists.txt
@@ -32,6 +32,7 @@ add_subdirectory(stdio)
 add_subdirectory(celix_threads)
 add_subdirectory(eventfd)
 add_subdirectory(celix_bundle_ctx)
+add_subdirectory(stat)
 
 celix_subproject(ERROR_INJECTOR_MDNSRESPONDER "Option to enable building the 
mdnsresponder error injector" OFF)
 if (ERROR_INJECTOR_MDNSRESPONDER)
diff --git a/libs/error_injector/stat/CMakeLists.txt 
b/libs/error_injector/stat/CMakeLists.txt
new file mode 100644
index 00000000..31ed0559
--- /dev/null
+++ b/libs/error_injector/stat/CMakeLists.txt
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+add_library(stat_ei STATIC src/stat_ei.cc)
+
+target_include_directories(stat_ei PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
+target_link_libraries(stat_ei PUBLIC Celix::error_injector)
+
+target_link_options(stat_ei INTERFACE
+        LINKER:--wrap,mkdir
+        LINKER:--wrap,stat
+        )
+add_library(Celix::stat_ei ALIAS stat_ei)
diff --git a/libs/error_injector/stat/include/stat_ei.h 
b/libs/error_injector/stat/include/stat_ei.h
new file mode 100644
index 00000000..439a9bab
--- /dev/null
+++ b/libs/error_injector/stat/include/stat_ei.h
@@ -0,0 +1,37 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+ */
+
+#ifndef CELIX_STAT_EI_H
+#define CELIX_STAT_EI_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "celix_error_injector.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+
+CELIX_EI_DECLARE(mkdir, int);
+
+CELIX_EI_DECLARE(stat, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //CELIX_STAT_EI_H
diff --git a/libs/error_injector/stat/src/stat_ei.cc 
b/libs/error_injector/stat/src/stat_ei.cc
new file mode 100644
index 00000000..7edf5744
--- /dev/null
+++ b/libs/error_injector/stat/src/stat_ei.cc
@@ -0,0 +1,43 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+ */
+
+#include "stat_ei.h"
+#include <errno.h>
+
+extern "C" {
+
+int __real_mkdir (const char *__path, __mode_t __mode);
+CELIX_EI_DEFINE(mkdir, int)
+int __wrap_mkdir (const char *__path, __mode_t __mode) {
+    errno = EACCES;
+    CELIX_EI_IMPL(mkdir);
+    errno = 0;
+    return __real_mkdir(__path, __mode);
+}
+
+
+int __real_stat (const char *__restrict __file, struct stat *__restrict __buf);
+CELIX_EI_DEFINE(stat, int)
+int __wrap_stat (const char *__restrict __file, struct stat *__restrict __buf) 
{
+    errno = EOVERFLOW;
+    CELIX_EI_IMPL(stat);
+    errno = 0;
+    return __real_stat(__file, __buf);
+}
+}
\ No newline at end of file
diff --git a/libs/utils/gtest/CMakeLists.txt b/libs/utils/gtest/CMakeLists.txt
index 20ba6e44..2527d6a0 100644
--- a/libs/utils/gtest/CMakeLists.txt
+++ b/libs/utils/gtest/CMakeLists.txt
@@ -80,7 +80,7 @@ if (LINKER_WRAP_SUPPORTED)
     add_executable(test_utils_with_ei
             src/FileUtilsErrorInjectionTestSuite.cc
             )
-    target_link_libraries(test_utils_with_ei PRIVATE Celix::zip_ei 
Celix::stdio_ei Celix::utils_obj Celix::utils_ei GTest::gtest GTest::gtest_main)
+    target_link_libraries(test_utils_with_ei PRIVATE Celix::zip_ei 
Celix::stdio_ei Celix::stat_ei Celix::utils_obj Celix::utils_ei GTest::gtest 
GTest::gtest_main)
     target_include_directories(test_utils_with_ei PRIVATE ../src) #for 
version_private (needs refactoring of test)
     celix_deprecated_utils_headers(test_utils_with_ei)
     add_dependencies(test_utils_with_ei test_utils_resources)
diff --git a/libs/utils/gtest/src/FileUtilsErrorInjectionTestSuite.cc 
b/libs/utils/gtest/src/FileUtilsErrorInjectionTestSuite.cc
index c0b60a68..139b95a6 100644
--- a/libs/utils/gtest/src/FileUtilsErrorInjectionTestSuite.cc
+++ b/libs/utils/gtest/src/FileUtilsErrorInjectionTestSuite.cc
@@ -17,6 +17,7 @@
  * under the License.
  */
 
+#include <fstream>
 #include <gtest/gtest.h>
 #include <stdlib.h>
 #include <string>
@@ -27,6 +28,7 @@
 #include "celix_file_utils.h"
 #include "celix_properties.h"
 #include "celix_utils_ei.h"
+#include "stat_ei.h"
 #include "stdio_ei.h"
 #include "zip_ei.h"
 
@@ -40,6 +42,8 @@ public:
         celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr);
         celix_ei_expect_fopen(nullptr, 0, nullptr);
         celix_ei_expect_fwrite(nullptr, 0, 0);
+        celix_ei_expect_mkdir(nullptr, 0, 0);
+        celix_ei_expect_stat(nullptr, 0, 0);
     }
 };
 
@@ -98,15 +102,49 @@ TEST_F(FileUtilsWithErrorInjectionTestSuite, 
ExtractZipFileTest) {
 }
 
 TEST_F(FileUtilsWithErrorInjectionTestSuite, CreateDirectory) {
-    const char* testDir = "celix_file_utils_test/directory";
-    celix_utils_deleteDirectory(testDir, nullptr);
+    const std::string root = "celix_file_utils_test";
+    const std::string testDir = root + "/directory";
+    celix_utils_deleteDirectory(root.c_str(), nullptr);
 
-    //I can create a new directory.
     const char* error = nullptr;
-    EXPECT_FALSE(celix_utils_directoryExists(testDir));
+    EXPECT_FALSE(celix_utils_directoryExists(testDir.c_str()));
     celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr);
-    auto status = celix_utils_createDirectory(testDir, true, &error);
+    auto status = celix_utils_createDirectory(testDir.c_str(), true, &error);
     EXPECT_EQ(status, CELIX_ENOMEM);
     EXPECT_NE(error, nullptr);
-    EXPECT_FALSE(celix_utils_fileExists(testDir));
+    EXPECT_FALSE(celix_utils_fileExists(testDir.c_str()));
+
+    status = celix_utils_createDirectory(root.c_str(), true, &error);
+    EXPECT_EQ(status, CELIX_SUCCESS);
+    const std::string invalidDir = root + "/file/directory";
+    const std::string filename = invalidDir.substr(0, invalidDir.rfind('/'));
+    // Create file to make directory path invalid
+    std::fstream file(filename, std::ios::out);
+    file.close();
+
+    status = celix_utils_createDirectory(filename.c_str(), true, &error);
+    EXPECT_EQ(status, CELIX_FILE_IO_EXCEPTION);
+
+    status = celix_utils_createDirectory(invalidDir.c_str(), true, &error);
+    EXPECT_EQ(status, CELIX_ERROR_MAKE(CELIX_FACILITY_CERRNO,ENOTDIR));
+
+    celix_utils_deleteDirectory(root.c_str(), nullptr);
+    celix_ei_expect_mkdir(CELIX_EI_UNKNOWN_CALLER, 0, -1);
+    status = celix_utils_createDirectory(testDir.c_str(), true, &error);
+    EXPECT_EQ(status, CELIX_ERROR_MAKE(CELIX_FACILITY_CERRNO,EACCES));
+    EXPECT_NE(error, nullptr);
+
+    celix_utils_deleteDirectory(root.c_str(), nullptr);
+    celix_ei_expect_mkdir(CELIX_EI_UNKNOWN_CALLER, 0, -1, 2);
+    status = celix_utils_createDirectory(testDir.c_str(), true, &error);
+    EXPECT_EQ(status, CELIX_ERROR_MAKE(CELIX_FACILITY_CERRNO,EACCES));
+    EXPECT_NE(error, nullptr);
+
+    celix_utils_deleteDirectory(root.c_str(), nullptr);
+    status = celix_utils_createDirectory(root.c_str(), true, &error);
+    EXPECT_EQ(status, CELIX_SUCCESS);
+    celix_ei_expect_stat(CELIX_EI_UNKNOWN_CALLER, 0, -1, 2);
+    status = celix_utils_createDirectory(testDir.c_str(), true, &error);
+    EXPECT_EQ(status, CELIX_ERROR_MAKE(CELIX_FACILITY_CERRNO,EOVERFLOW));
+    EXPECT_NE(error, nullptr);
 }
\ No newline at end of file
diff --git a/libs/utils/gtest/src/FileUtilsTestSuite.cc 
b/libs/utils/gtest/src/FileUtilsTestSuite.cc
index cdb412bb..79bc80ea 100644
--- a/libs/utils/gtest/src/FileUtilsTestSuite.cc
+++ b/libs/utils/gtest/src/FileUtilsTestSuite.cc
@@ -57,7 +57,6 @@ TEST_F(FileUtilsTestSuite, CreateAndDeleteDirectory) {
     EXPECT_TRUE(celix_utils_fileExists(testDir));
     EXPECT_TRUE(celix_utils_directoryExists(testDir));
 
-
     //Creating a directory if it already exists fails when using 
failIfPresent=true.
     status = celix_utils_createDirectory(testDir, true, &error);
     EXPECT_NE(status, CELIX_SUCCESS);
diff --git a/libs/utils/src/celix_file_utils.c 
b/libs/utils/src/celix_file_utils.c
index 97689995..030f31ec 100644
--- a/libs/utils/src/celix_file_utils.c
+++ b/libs/utils/src/celix_file_utils.c
@@ -56,16 +56,19 @@ static int maybe_mkdir(const char* path, mode_t mode)
     errno = 0;
 
     /* Try to make the directory */
-    if (mkdir(path, mode) == 0)
+    if (mkdir(path, mode) == 0) {
         return 0;
+    }
 
     /* If it fails for any reason but EEXIST, fail */
-    if (errno != EEXIST)
+    if (errno != EEXIST) {
         return -1;
+    }
 
     /* Check if the existing path is a directory */
-    if (stat(path, &st) != 0)
+    if (stat(path, &st) != 0) {
         return -1;
+    }
 
     /* If not, fail with ENOTDIR */
     if (!S_ISDIR(st.st_mode)) {
@@ -116,8 +119,9 @@ celix_status_t celix_utils_createDirectory(const char* 
path, bool failIfPresent,
     errno = 0;
     /* Copy string so it's mutable */
     _path = celix_utils_strdup(path);
-    if (_path == NULL)
+    if (_path == NULL) {
         goto out;
+    }
 
     /* Iterate the string */
     for (p = _path + 1; *p; p++) {

Reply via email to