• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "atomicfile_mock.h"
17 
18 #include <dlfcn.h>
19 
20 namespace OHOS::FileManagement::ModuleFileIO::Test {
21 using namespace OHOS::FileManagement::ModuleFileIO;
22 
23 thread_local std::shared_ptr<AtomicfileMock> AtomicfileMock::atomicfileMock = nullptr;
24 thread_local bool AtomicfileMock::mockable = false;
25 
GetMock()26 std::shared_ptr<AtomicfileMock> AtomicfileMock::GetMock()
27 {
28     if (atomicfileMock == nullptr) {
29         atomicfileMock = std::make_shared<AtomicfileMock>();
30     }
31     return atomicfileMock;
32 }
33 
EnableMock()34 void AtomicfileMock::EnableMock()
35 {
36     mockable = true;
37 }
38 
DisableMock()39 void AtomicfileMock::DisableMock()
40 {
41     atomicfileMock = nullptr;
42     mockable = false;
43 }
44 
IsMockable()45 bool AtomicfileMock::IsMockable()
46 {
47     return mockable;
48 }
49 
50 } // namespace OHOS::FileManagement::ModuleFileIO::Test
51 
52 #ifdef __cplusplus
53 using namespace OHOS::FileManagement::ModuleFileIO::Test;
54 
55 extern "C" {
rename(const char * old_filename,const char * new_filename)56 int rename(const char *old_filename, const char *new_filename)
57 {
58     if (AtomicfileMock::IsMockable()) {
59         return AtomicfileMock::GetMock()->rename(old_filename, new_filename);
60     }
61 
62     static int (*realRename)(const char *, const char *) = []() {
63         auto func = (int (*)(const char *, const char *))dlsym(RTLD_NEXT, "rename");
64         if (!func) {
65             GTEST_LOG_(ERROR) << "Failed to resolve real rename: " << dlerror();
66         }
67         return func;
68     }();
69 
70     if (!realRename) {
71         return -1;
72     }
73 
74     return realRename(old_filename, new_filename);
75 }
76 
remove(const char * filename)77 int remove(const char *filename)
78 {
79     if (AtomicfileMock::IsMockable()) {
80         return AtomicfileMock::GetMock()->remove(filename);
81     }
82 
83     static int (*realRemove)(const char *) = []() {
84         auto func = (int (*)(const char *))dlsym(RTLD_NEXT, "remove");
85         if (!func) {
86             GTEST_LOG_(ERROR) << "Failed to resolve real remove: " << dlerror();
87         }
88         return func;
89     }();
90 
91     if (!realRemove) {
92         return -1;
93     }
94 
95     return realRemove(filename);
96 }
97 
napi_get_reference_value(napi_env env,napi_ref ref,napi_value * result)98 napi_status napi_get_reference_value(napi_env env, napi_ref ref, napi_value *result)
99 {
100     if (AtomicfileMock::IsMockable()) {
101         return AtomicfileMock::GetMock()->napi_get_reference_value(env, ref, result);
102     }
103 
104     static napi_status (*realNapi)(napi_env, napi_ref, napi_value *) = []() {
105         auto func = (napi_status(*)(napi_env, napi_ref, napi_value *))dlsym(RTLD_NEXT, "napi_get_reference_value");
106         if (!func) {
107             GTEST_LOG_(ERROR) << "Failed to resolve real napi_get_reference_value: " << dlerror();
108         }
109         return func;
110     }();
111 
112     if (!realNapi) {
113         return napi_ok;
114     }
115 
116     return realNapi(env, ref, result);
117 }
118 
napi_delete_reference(napi_env env,napi_ref ref)119 napi_status napi_delete_reference(napi_env env, napi_ref ref)
120 {
121     if (AtomicfileMock::IsMockable()) {
122         return AtomicfileMock::GetMock()->napi_delete_reference(env, ref);
123     }
124 
125     static napi_status (*realNapi)(napi_env, napi_ref) = []() {
126         auto func = (napi_status(*)(napi_env, napi_ref))dlsym(RTLD_NEXT, "napi_delete_reference");
127         if (!func) {
128             GTEST_LOG_(ERROR) << "Failed to resolve real napi_delete_reference: " << dlerror();
129         }
130         return func;
131     }();
132 
133     if (!realNapi) {
134         return napi_ok;
135     }
136 
137     return realNapi(env, ref);
138 }
139 
napi_unwrap(napi_env env,napi_value js_object,void ** result)140 napi_status napi_unwrap(napi_env env, napi_value js_object, void **result)
141 {
142     if (AtomicfileMock::IsMockable()) {
143         return AtomicfileMock::GetMock()->napi_unwrap(env, js_object, result);
144     }
145 
146     static napi_status (*realNapi)(napi_env, napi_value, void **) = []() {
147         auto func = (napi_status(*)(napi_env, napi_value, void **))dlsym(RTLD_NEXT, "napi_unwrap");
148         if (!func) {
149             GTEST_LOG_(ERROR) << "Failed to resolve real napi_unwrap: " << dlerror();
150         }
151         return func;
152     }();
153 
154     if (!realNapi) {
155         return napi_ok;
156     }
157 
158     return realNapi(env, js_object, result);
159 }
160 
napi_typeof(napi_env env,napi_value value,napi_valuetype * result)161 napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype *result)
162 {
163     return AtomicfileMock::GetMock()->napi_typeof(env, value, result);
164 }
165 } // extern "C"
166 
InitArgs(std::function<bool ()> argcChecker)167 bool NFuncArg::InitArgs(std::function<bool()> argcChecker)
168 {
169     if (AtomicfileMock::IsMockable()) {
170         return AtomicfileMock::GetMock()->InitArgs(argcChecker);
171     }
172 
173     static bool (*realInitArgs)(std::function<bool()>) = []() {
174         auto func = (bool (*)(std::function<bool()>))dlsym(RTLD_NEXT, "InitArgs");
175         if (!func) {
176             GTEST_LOG_(ERROR) << "Failed to resolve real InitArgs: " << dlerror();
177         }
178         return func;
179     }();
180 
181     if (!realInitArgs) {
182         return false;
183     }
184 
185     return realInitArgs(argcChecker);
186 }
187 
GetThisVar() const188 napi_value NFuncArg::GetThisVar() const
189 {
190     if (AtomicfileMock::IsMockable()) {
191         return AtomicfileMock::GetMock()->GetThisVar();
192     }
193 
194     static napi_value (*realGetThisVar)() = []() {
195         auto func = (napi_value(*)())dlsym(RTLD_NEXT, "GetThisVar");
196         if (!func) {
197             GTEST_LOG_(ERROR) << "Failed to resolve real GetThisVar: " << dlerror();
198         }
199         return func;
200     }();
201 
202     if (!realGetThisVar) {
203         return nullptr;
204     }
205 
206     return realGetThisVar();
207 }
208 
ThrowErr(napi_env env,std::string errMsg)209 void NError::ThrowErr(napi_env env, std::string errMsg)
210 {
211     if (AtomicfileMock::IsMockable()) {
212         return AtomicfileMock::GetMock()->ThrowErr(env, errMsg);
213     }
214 
215     static void (*realThrowErr)(napi_env, std::string) = []() {
216         auto func = (void (*)(napi_env, std::string))dlsym(RTLD_NEXT, "ThrowErr");
217         if (!func) {
218             GTEST_LOG_(ERROR) << "Failed to resolve real ThrowErr: " << dlerror();
219         }
220         return func;
221     }();
222 
223     if (!realThrowErr) {
224         return;
225     }
226 
227     return realThrowErr(env, errMsg);
228 }
229 #endif