• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include <cerrno>
16 #include <chrono>
17 #include <gtest/gtest.h>
18 #include <securec.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <thread>
22 
23 #include "c_mock_common.h"
24 #define private public
25 #include "dlp_link_manager.h"
26 #undef private
27 #include "dlp_fuse_helper.h"
28 #include "dlp_permission.h"
29 #include "dlp_permission_log.h"
30 #include "fuse_daemon.h"
31 
32 namespace OHOS {
33 namespace Security {
34 namespace DlpPermission {
35 using namespace testing::ext;
36 
37 namespace {
38 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "FuseDaemonTest"};
39 
40 static const fuse_ino_t ROOT_INODE = 1;
41 static const int DEFAULT_ATTR_TIMEOUT = 10000;
42 static const uint32_t MAX_FUSE_READ_BUFF_SIZE = 10 * 1024 * 1024; // 10M
43 static const uint32_t MAX_READ_DIR_BUF_SIZE = 100 * 1024;  // 100K
44 
45 static int g_fuseReplyErr = 0;
46 static struct fuse_file_info g_fuseReplyOpen;
47 static struct fuse_entry_param g_fuseReplyEntry;
48 static struct stat g_fuseReplyAttr;
49 static double g_fuseReplyAttrTimeout = 0.0F;
50 static size_t g_fuseReplyBufSize = 0;
51 static int g_session;
52 static const std::string DLP_TEST_DIR = "/data/dlpTest/";
53 static DlpLinkManager* dlpLinkManager = nullptr;
54 constexpr int WAIT_SECOND = 1;
55 
FuseReplyErrMock(fuse_req_t req,int err)56 static int FuseReplyErrMock(fuse_req_t req, int err)
57 {
58     (void)req;
59     g_fuseReplyErr = err;
60     return 0;
61 }
62 
FuseReplyOpenMock(fuse_req_t req,const struct fuse_file_info * f)63 static int FuseReplyOpenMock(fuse_req_t req, const struct fuse_file_info *f)
64 {
65     (void)req;
66     g_fuseReplyOpen = *f;
67     return 0;
68 }
69 
FuseReplyEntryMock(fuse_req_t req,const struct fuse_entry_param * e)70 int FuseReplyEntryMock(fuse_req_t req, const struct fuse_entry_param *e)
71 {
72     (void)req;
73     g_fuseReplyEntry = *e;
74     return 0;
75 }
76 
FuseReplyAttrMock(fuse_req_t req,const struct stat * attr,double attr_timeout)77 int FuseReplyAttrMock(fuse_req_t req, const struct stat *attr, double attr_timeout)
78 {
79     (void)req;
80     g_fuseReplyAttr = *attr;
81     g_fuseReplyAttrTimeout = attr_timeout;
82     return 0;
83 }
84 
85 static const size_t ADD_DIRENTRY_BUFF_LEN = 100;
FuseAddDirentryMockCurDirFail(fuse_req_t req,char * buf,size_t bufsize,const char * name,const struct stat * stbuf,off_t off)86 size_t FuseAddDirentryMockCurDirFail(fuse_req_t req, char *buf, size_t bufsize,
87     const char *name, const struct stat *stbuf, off_t off)
88 {
89     (void)req;
90     (void)buf;
91     (void)bufsize;
92     (void)name;
93     (void)stbuf;
94     (void)off;
95     return ADD_DIRENTRY_BUFF_LEN + 1;
96 }
97 
FuseAddDirentryMockUpperDirFail(fuse_req_t req,char * buf,size_t bufsize,const char * name,const struct stat * stbuf,off_t off)98 size_t FuseAddDirentryMockUpperDirFail(fuse_req_t req, char *buf, size_t bufsize,
99     const char *name, const struct stat *stbuf, off_t off)
100 {
101     (void)req;
102     (void)buf;
103     (void)bufsize;
104     (void)stbuf;
105     (void)off;
106     if (strcmp(name, ".") == 0) {
107         return strlen(".");
108     }
109     return ADD_DIRENTRY_BUFF_LEN + 1;
110 }
111 
FuseAddDirentryMockTestFileFail(fuse_req_t req,char * buf,size_t bufsize,const char * name,const struct stat * stbuf,off_t off)112 size_t FuseAddDirentryMockTestFileFail(fuse_req_t req, char *buf, size_t bufsize,
113     const char *name, const struct stat *stbuf, off_t off)
114 {
115     (void)req;
116     (void)buf;
117     (void)bufsize;
118     (void)stbuf;
119     (void)off;
120     if (strcmp(name, "test") != 0) {
121         return strlen(name);
122     }
123     return ADD_DIRENTRY_BUFF_LEN + 1;
124 }
125 
FuseReplyBufMock(fuse_req_t req,const char * buf,size_t size)126 int FuseReplyBufMock(fuse_req_t req, const char *buf, size_t size)
127 {
128     (void)req;
129     (void)buf;
130     (void)size;
131     g_fuseReplyBufSize = 0;
132     return 0;
133 }
134 
135 
FuseSessionNewMock(struct fuse_args * args,const struct fuse_lowlevel_ops * op,size_t opSize,void * userdata)136 struct fuse_session *FuseSessionNewMock(struct fuse_args *args, const struct fuse_lowlevel_ops *op,
137     size_t opSize, void *userdata)
138 {
139     (void)args;
140     (void)op;
141     (void)opSize;
142     (void)userdata;
143     return reinterpret_cast<struct fuse_session *>(&g_session);
144 }
145 
FuseSessionMountMock(struct fuse_session * se,const char * mountpoint)146 int FuseSessionMountMock(struct fuse_session *se, const char *mountpoint)
147 {
148     (void)se;
149     (void)mountpoint;
150     return 0;
151 }
152 
GetDlpLinkManager(int timeout)153 static bool GetDlpLinkManager(int timeout)
154 {
155     auto start = std::chrono::system_clock::now();
156     while (std::chrono::system_clock::now() - start < std::chrono::seconds(timeout)) {
157         dlpLinkManager = DlpFuseHelper::GetDlpLinkManagerInstance();
158         if (dlpLinkManager) {
159             return true;
160         }
161         std::this_thread::yield();
162     }
163     return false;
164 }
165 }
166 
167 class FuseDaemonTest : public testing::Test {
168 public:
SetUpTestCase()169     static void SetUpTestCase()
170     {
171         struct stat fstat;
172         if (stat(DLP_TEST_DIR.c_str(), &fstat) != 0) {
173             if (errno == ENOENT) {
174                 int32_t ret = mkdir(DLP_TEST_DIR.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
175                 if (ret < 0) {
176                     DLP_LOG_ERROR(LABEL, "mkdir mount point failed errno %{public}d", errno);
177                     return;
178                 }
179             } else {
180                 DLP_LOG_ERROR(LABEL, "get mount point failed errno %{public}d", errno);
181                 return;
182             }
183         }
184 
185         if (!GetDlpLinkManager(WAIT_SECOND)) {
186             DLP_LOG_ERROR(LABEL, "get dlplinkmanger instance failed");
187             return;
188         }
189     };
190 
TearDownTestCase()191     static void TearDownTestCase()
192     {
193         rmdir(DLP_TEST_DIR.c_str());
194     };
195 
SetUp()196     void SetUp() {};
197 
TearDown()198     void TearDown() {};
199 };
200 
201 /**
202  * @tc.name: FuseDaemonLookup001
203  * @tc.desc: test fuse lookup callback abnormal branch
204  * @tc.type: FUNC
205  * @tc.require:AR000GVIGC
206  */
207 HWTEST_F(FuseDaemonTest, FuseDaemonLookup001, TestSize.Level1)
208 {
209     DLP_LOG_INFO(LABEL, "FuseDaemonLookup001");
210     DlpLinkFile linkfile("test", nullptr);
211     fuse_ino_t ino = static_cast<fuse_ino_t>(reinterpret_cast<uintptr_t>(&linkfile));
212     fuse_req_t req = nullptr;
213 
214     // file name null
215     DlpCMockCondition condition;
216     condition.mockSequence = { true };
217     SetMockConditions("fuse_reply_err", condition);
218     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
219     g_fuseReplyErr = 0;
220     FuseDaemon::fuseDaemonOper_.lookup(req, ROOT_INODE, nullptr);
221     EXPECT_EQ(ENOENT, g_fuseReplyErr);
222     CleanMockConditions();
223 
224     // ino != ROOT_INODE
225     condition.mockSequence = { true };
226     SetMockConditions("fuse_reply_err", condition);
227     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
228     g_fuseReplyErr = 0;
229     FuseDaemon::fuseDaemonOper_.lookup(req, ino, "test");
230     EXPECT_EQ(ENOENT, g_fuseReplyErr);
231     CleanMockConditions();
232 
233     // name = '.'
234     condition.mockSequence = { true };
235     SetMockConditions("fuse_reply_entry", condition);
236     SetMockCallback("fuse_reply_entry", reinterpret_cast<CommonMockFuncT>(FuseReplyEntryMock));
237     (void)memset_s(&g_fuseReplyEntry, sizeof(g_fuseReplyEntry), 0, sizeof(g_fuseReplyEntry));
238     FuseDaemon::fuseDaemonOper_.lookup(req, ROOT_INODE, ".");
239     EXPECT_EQ(ROOT_INODE, g_fuseReplyEntry.ino);
240     CleanMockConditions();
241 
242     // name = '..'
243     condition.mockSequence = { true };
244     SetMockConditions("fuse_reply_entry", condition);
245     SetMockCallback("fuse_reply_entry", reinterpret_cast<CommonMockFuncT>(FuseReplyEntryMock));
246     (void)memset_s(&g_fuseReplyEntry, sizeof(g_fuseReplyEntry), 0, sizeof(g_fuseReplyEntry));
247     FuseDaemon::fuseDaemonOper_.lookup(req, ROOT_INODE, "..");
248     EXPECT_EQ(ROOT_INODE, g_fuseReplyEntry.ino);
249     CleanMockConditions();
250 
251     // name = '..'
252     condition.mockSequence = { true };
253     SetMockConditions("fuse_reply_err", condition);
254     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
255     g_fuseReplyErr = 0;
256     FuseDaemon::fuseDaemonOper_.lookup(req, ROOT_INODE, "test");
257     EXPECT_EQ(ENOENT, g_fuseReplyErr);
258     CleanMockConditions();
259 }
260 
261 /**
262  * @tc.name: FuseDaemonGetattr001
263  * @tc.desc: test fuse getattr callback abnormal branch
264  * @tc.type: FUNC
265  * @tc.require:AR000GVIGC
266  */
267 HWTEST_F(FuseDaemonTest, FuseDaemonGetattr001, TestSize.Level1)
268 {
269     DLP_LOG_INFO(LABEL, "FuseDaemonGetattr001");
270     fuse_req_t req = nullptr;
271 
272     // get ROOT_INODE attr
273     DlpCMockCondition condition;
274     condition.mockSequence = { true };
275     SetMockConditions("fuse_reply_attr", condition);
276     SetMockCallback("fuse_reply_attr", reinterpret_cast<CommonMockFuncT>(FuseReplyAttrMock));
277     (void)memset_s(&g_fuseReplyAttr, sizeof(g_fuseReplyAttr), 0, sizeof(g_fuseReplyAttr));
278     g_fuseReplyAttrTimeout = 0.0F;
279     FuseDaemon::fuseDaemonOper_.getattr(req, ROOT_INODE, nullptr);
280     EXPECT_EQ(memcmp(&FuseDaemon::rootFileStat_, &g_fuseReplyAttr, sizeof(struct stat)), 0);
281     EXPECT_EQ(DEFAULT_ATTR_TIMEOUT, g_fuseReplyAttrTimeout);
282     CleanMockConditions();
283 
284     // get not exist link file
285     SetMockConditions("fuse_reply_err", condition);
286     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
287     g_fuseReplyErr = 0;
288     FuseDaemon::fuseDaemonOper_.getattr(req, 0, nullptr);
289     EXPECT_EQ(ENOENT, g_fuseReplyErr);
290     CleanMockConditions();
291 }
292 
293 /**
294  * @tc.name: FuseDaemonOpen001
295  * @tc.desc: test fuse open callback abnormal branch
296  * @tc.type: FUNC
297  * @tc.require:AR000GVIGC
298  */
299 HWTEST_F(FuseDaemonTest, FuseDaemonOpen001, TestSize.Level1)
300 {
301     DLP_LOG_INFO(LABEL, "FuseDaemonOpen001");
302     fuse_req_t req = nullptr;
303 
304     // open ROOT_INODE
305     DlpCMockCondition condition;
306     condition.mockSequence = { true };
307     SetMockConditions("fuse_reply_err", condition);
308     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
309     g_fuseReplyErr = 0;
310     FuseDaemon::fuseDaemonOper_.open(req, ROOT_INODE, nullptr);
311     EXPECT_EQ(ENOENT, g_fuseReplyErr);
312     CleanMockConditions();
313 
314     // open null file
315     condition.mockSequence = { true };
316     SetMockConditions("fuse_reply_err", condition);
317     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
318     g_fuseReplyErr = 0;
319     FuseDaemon::fuseDaemonOper_.open(req, 0, nullptr);
320     EXPECT_EQ(ENOENT, g_fuseReplyErr);
321     CleanMockConditions();
322 
323     // open readonly dlp with O_TRUNC
324     std::shared_ptr<DlpFile> dlpFile = std::make_shared<DlpFile>(-1, DLP_TEST_DIR, 0, false);
325     ASSERT_NE(dlpFile, nullptr);
326     DlpLinkFile linkfile("test", dlpFile);
327     fuse_ino_t ino = static_cast<fuse_ino_t>(reinterpret_cast<uintptr_t>(&linkfile));
328     struct fuse_file_info fi;
329     fi.flags = O_TRUNC;
330 
331     condition.mockSequence = { true };
332     SetMockConditions("fuse_reply_err", condition);
333     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
334     g_fuseReplyErr = 0;
335     FuseDaemon::fuseDaemonOper_.open(req, ino, &fi);
336     EXPECT_EQ(EINVAL, g_fuseReplyErr);
337     CleanMockConditions();
338 
339     fi.flags = O_RDWR;
340     condition.mockSequence = { true };
341     SetMockConditions("fuse_reply_open", condition);
342     SetMockCallback("fuse_reply_open", reinterpret_cast<CommonMockFuncT>(FuseReplyOpenMock));
343     (void)memset_s(&g_fuseReplyOpen, sizeof(g_fuseReplyOpen), 0, sizeof(g_fuseReplyOpen));
344     FuseDaemon::fuseDaemonOper_.open(req, ino, &fi);
345     EXPECT_EQ(O_RDWR, g_fuseReplyOpen.flags);
346     CleanMockConditions();
347 }
348 
349 /**
350  * @tc.name: FuseDaemonRead001
351  * @tc.desc: test fuse read callback abnormal branch
352  * @tc.type: FUNC
353  * @tc.require:AR000GVIGC
354  */
355 HWTEST_F(FuseDaemonTest, FuseDaemonRead001, TestSize.Level1)
356 {
357     DLP_LOG_INFO(LABEL, "FuseDaemonRead001");
358     fuse_req req;
359     req.ctx.uid = getuid();
360 
361     // offset < 0
362     DlpCMockCondition condition;
363     condition.mockSequence = { true };
364     SetMockConditions("fuse_reply_err", condition);
365     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
366     g_fuseReplyErr = 0;
367     FuseDaemon::fuseDaemonOper_.read(&req, ROOT_INODE, 1, -1, nullptr);
368     EXPECT_EQ(EINVAL, g_fuseReplyErr);
369     CleanMockConditions();
370 
371     // offset > DLP_MAX_CONTENT_SIZE
372     condition.mockSequence = { true };
373     SetMockConditions("fuse_reply_err", condition);
374     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
375     g_fuseReplyErr = 0;
376     FuseDaemon::fuseDaemonOper_.read(&req, ROOT_INODE, 1, DLP_MAX_CONTENT_SIZE + 1, nullptr);
377     EXPECT_EQ(EINVAL, g_fuseReplyErr);
378     CleanMockConditions();
379 
380     // size > MAX_FUSE_READ_BUFF_SIZE
381     condition.mockSequence = { true };
382     SetMockConditions("fuse_reply_err", condition);
383     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
384     g_fuseReplyErr = 0;
385     FuseDaemon::fuseDaemonOper_.read(&req, ROOT_INODE, MAX_FUSE_READ_BUFF_SIZE + 1, 0, nullptr);
386     EXPECT_EQ(EINVAL, g_fuseReplyErr);
387     CleanMockConditions();
388 }
389 
390 /**
391  * @tc.name: FuseDaemonRead002
392  * @tc.desc: test fuse read callback abnormal branch2
393  * @tc.type: FUNC
394  * @tc.require:AR000GVIGC
395  */
396 HWTEST_F(FuseDaemonTest, FuseDaemonRead002, TestSize.Level1)
397 {
398     DLP_LOG_INFO(LABEL, "FuseDaemonRead002");
399     fuse_req req;
400     req.ctx.uid = getuid();
401 
402     // ino ROOT_INODE
403     DlpCMockCondition condition;
404     condition.mockSequence = { true };
405     SetMockConditions("fuse_reply_err", condition);
406     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
407     g_fuseReplyErr = 0;
408     FuseDaemon::fuseDaemonOper_.read(&req, ROOT_INODE, 10, 0, nullptr);
409     EXPECT_EQ(ENOENT, g_fuseReplyErr);
410     CleanMockConditions();
411 
412     // ino 0
413     condition.mockSequence = { true };
414     SetMockConditions("fuse_reply_err", condition);
415     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
416     g_fuseReplyErr = 0;
417     FuseDaemon::fuseDaemonOper_.read(&req, 0, 10, 0, nullptr);
418     EXPECT_EQ(EBADF, g_fuseReplyErr);
419     CleanMockConditions();
420 
421     // can not read dlp file
422     std::shared_ptr<DlpFile> dlpFile = std::make_shared<DlpFile>(-1, DLP_TEST_DIR, 0, false);
423     ASSERT_NE(dlpFile, nullptr);
424     DlpLinkFile linkfile("test", dlpFile);
425     fuse_ino_t ino = static_cast<fuse_ino_t>(reinterpret_cast<uintptr_t>(&linkfile));
426 
427     condition.mockSequence = { true };
428     SetMockConditions("fuse_reply_err", condition);
429     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
430     g_fuseReplyErr = 0;
431     FuseDaemon::fuseDaemonOper_.read(&req, ino, 10, 0, nullptr);
432     EXPECT_EQ(EIO, g_fuseReplyErr);
433     CleanMockConditions();
434 }
435 
436 /**
437  * @tc.name: FuseDaemonWrite001
438  * @tc.desc: test fuse write callback abnormal branch
439  * @tc.type: FUNC
440  * @tc.require:AR000GVIGC
441  */
442 HWTEST_F(FuseDaemonTest, FuseDaemonWrite001, TestSize.Level1)
443 {
444     DLP_LOG_INFO(LABEL, "FuseDaemonWrite001");
445     fuse_req_t req = nullptr;
446 
447     // offset < 0
448     DlpCMockCondition condition;
449     condition.mockSequence = { true };
450     SetMockConditions("fuse_reply_err", condition);
451     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
452     g_fuseReplyErr = 0;
453     FuseDaemon::fuseDaemonOper_.write(req, ROOT_INODE, nullptr, 1, -1, nullptr);
454     EXPECT_EQ(EINVAL, g_fuseReplyErr);
455     CleanMockConditions();
456 
457     // offset > DLP_MAX_CONTENT_SIZE
458     condition.mockSequence = { true };
459     SetMockConditions("fuse_reply_err", condition);
460     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
461     g_fuseReplyErr = 0;
462     FuseDaemon::fuseDaemonOper_.write(req, ROOT_INODE, nullptr, 1, DLP_MAX_CONTENT_SIZE + 1, nullptr);
463     EXPECT_EQ(EINVAL, g_fuseReplyErr);
464     CleanMockConditions();
465 
466     // size > DLP_FUSE_MAX_BUFFLEN
467     condition.mockSequence = { true };
468     SetMockConditions("fuse_reply_err", condition);
469     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
470     g_fuseReplyErr = 0;
471     FuseDaemon::fuseDaemonOper_.write(req, ROOT_INODE, nullptr, DLP_FUSE_MAX_BUFFLEN + 1, 100, nullptr);
472     EXPECT_EQ(EINVAL, g_fuseReplyErr);
473     CleanMockConditions();
474 
475     // ino ROOT_INODE
476     condition.mockSequence = { true };
477     SetMockConditions("fuse_reply_err", condition);
478     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
479     g_fuseReplyErr = 0;
480     FuseDaemon::fuseDaemonOper_.write(req, ROOT_INODE, nullptr, 1, 0, nullptr);
481     EXPECT_EQ(ENOENT, g_fuseReplyErr);
482     CleanMockConditions();
483 
484     // can not write dlp file
485     std::shared_ptr<DlpFile> dlpFile = std::make_shared<DlpFile>(-1, DLP_TEST_DIR, 0, false);
486     ASSERT_NE(dlpFile, nullptr);
487     DlpLinkFile linkfile("test", dlpFile);
488     fuse_ino_t ino = static_cast<fuse_ino_t>(reinterpret_cast<uintptr_t>(&linkfile));
489 
490     condition.mockSequence = { true };
491     SetMockConditions("fuse_reply_err", condition);
492     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
493     g_fuseReplyErr = 0;
494     FuseDaemon::fuseDaemonOper_.write(req, ino, nullptr, 1, 0, nullptr);
495     EXPECT_EQ(EIO, g_fuseReplyErr);
496     CleanMockConditions();
497 }
498 
499 /**
500  * @tc.name: FuseDaemonForget001
501  * @tc.desc: test fuse forget callback abnormal branch
502  * @tc.type: FUNC
503  * @tc.require:AR000GVIGC
504  */
505 HWTEST_F(FuseDaemonTest, FuseDaemonForget001, TestSize.Level1)
506 {
507     DLP_LOG_INFO(LABEL, "FuseDaemonForget001");
508     fuse_req_t req = nullptr;
509 
510     // ino ROOT_INODE
511     DlpCMockCondition condition;
512     condition.mockSequence = { true };
513     SetMockConditions("fuse_reply_err", condition);
514     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
515     g_fuseReplyErr = 0;
516     FuseDaemon::fuseDaemonOper_.forget(req, ROOT_INODE, 1);
517     EXPECT_EQ(ENOENT, g_fuseReplyErr);
518     CleanMockConditions();
519 
520     condition.mockSequence = { true };
521     SetMockConditions("fuse_reply_err", condition);
522     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
523     g_fuseReplyErr = 0;
524     FuseDaemon::fuseDaemonOper_.forget(req, 0, 1);
525     EXPECT_EQ(EBADF, g_fuseReplyErr);
526     CleanMockConditions();
527 }
528 
529 /**
530  * @tc.name: FuseDaemonReadDir001
531  * @tc.desc: test fuse read dir callback abnormal branch
532  * @tc.type: FUNC
533  * @tc.require:AR000GVIGC
534  */
535 HWTEST_F(FuseDaemonTest, FuseDaemonReadDir001, TestSize.Level1)
536 {
537     DLP_LOG_INFO(LABEL, "FuseDaemonReadDir001");
538     fuse_req_t req = nullptr;
539 
540     // off < 0
541     DlpCMockCondition condition;
542     condition.mockSequence = { true };
543     SetMockConditions("fuse_reply_err", condition);
544     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
545     g_fuseReplyErr = 0;
546     FuseDaemon::fuseDaemonOper_.readdir(req, ROOT_INODE, 10, -1, nullptr);
547     EXPECT_EQ(ENOTDIR, g_fuseReplyErr);
548 
549     // off > DLP_MAX_CONTENT_SIZE
550     condition.mockSequence = { true };
551     SetMockConditions("fuse_reply_err", condition);
552     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
553     g_fuseReplyErr = 0;
554     FuseDaemon::fuseDaemonOper_.readdir(req, ROOT_INODE, 10, DLP_MAX_CONTENT_SIZE + 1, nullptr);
555     EXPECT_EQ(ENOTDIR, g_fuseReplyErr);
556     CleanMockConditions();
557 
558     // ino != ROOT_INODE
559     condition.mockSequence = { true };
560     SetMockConditions("fuse_reply_err", condition);
561     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
562     g_fuseReplyErr = 0;
563     FuseDaemon::fuseDaemonOper_.readdir(req, 0, 10, 0, nullptr);
564     EXPECT_EQ(ENOTDIR, g_fuseReplyErr);
565     CleanMockConditions();
566 
567     // size > MAX_READ_DIR_BUF_SIZE
568     condition.mockSequence = { true };
569     SetMockConditions("fuse_reply_err", condition);
570     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
571     g_fuseReplyErr = 0;
572     FuseDaemon::fuseDaemonOper_.readdir(req, ROOT_INODE, MAX_READ_DIR_BUF_SIZE + 1, 0, nullptr);
573     EXPECT_EQ(EINVAL, g_fuseReplyErr);
574     CleanMockConditions();
575 }
576 
577 /**
578  * @tc.name: FuseDaemonReadDir002
579  * @tc.desc: test fuse AddDirentry callback CUR_DIR entry too large
580  * @tc.type: FUNC
581  * @tc.require:AR000GVIGC
582  */
583 HWTEST_F(FuseDaemonTest, FuseDaemonReadDir002, TestSize.Level1)
584 {
585     DLP_LOG_INFO(LABEL, "FuseDaemonReadDir002");
586     fuse_req_t req = nullptr;
587 
588     DlpCMockCondition condition;
589     condition.mockSequence = { true };
590     SetMockConditions("fuse_reply_err", condition);
591     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
592 
593     DlpCMockCondition condition1;
594     condition1.mockSequence = { true };
595     SetMockConditions("fuse_add_direntry", condition1);
596     SetMockCallback("fuse_add_direntry", reinterpret_cast<CommonMockFuncT>(FuseAddDirentryMockCurDirFail));
597 
598     g_fuseReplyErr = 0;
599     FuseDaemon::fuseDaemonOper_.readdir(req, ROOT_INODE, ADD_DIRENTRY_BUFF_LEN, 0, nullptr);
600     EXPECT_EQ(EINVAL, g_fuseReplyErr);
601     CleanMockConditions();
602 }
603 
604 /**
605  * @tc.name: FuseDaemonReadDir003
606  * @tc.desc: test fuse AddDirentry callback UPPER_DIR entry too large
607  * @tc.type: FUNC
608  * @tc.require:AR000GVIGC
609  */
610 HWTEST_F(FuseDaemonTest, FuseDaemonReadDir003, TestSize.Level1)
611 {
612     DLP_LOG_INFO(LABEL, "FuseDaemonReadDir003");
613     fuse_req_t req = nullptr;
614 
615     DlpCMockCondition condition;
616     condition.mockSequence = { true };
617     SetMockConditions("fuse_reply_err", condition);
618     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
619 
620     DlpCMockCondition condition1;
621     condition1.mockSequence = { true, true, true };
622     SetMockConditions("fuse_add_direntry", condition1);
623     SetMockCallback("fuse_add_direntry", reinterpret_cast<CommonMockFuncT>(FuseAddDirentryMockUpperDirFail));
624 
625     g_fuseReplyErr = 0;
626     FuseDaemon::fuseDaemonOper_.readdir(req, ROOT_INODE, ADD_DIRENTRY_BUFF_LEN, 0, nullptr);
627     EXPECT_EQ(EINVAL, g_fuseReplyErr);
628     CleanMockConditions();
629 }
630 
631 /**
632  * @tc.name: FuseDaemonReadDir004
633  * @tc.desc: test fuse AddDirentry callback test file entry fail
634  * @tc.type: FUNC
635  * @tc.require:AR000GVIGC
636  */
637 HWTEST_F(FuseDaemonTest, FuseDaemonReadDir004, TestSize.Level1)
638 {
639     DLP_LOG_INFO(LABEL, "FuseDaemonReadDir004");
640     fuse_req_t req = nullptr;
641     std::shared_ptr<DlpFile> filePtr = std::make_shared<DlpFile>(-1, DLP_TEST_DIR, 0, false);
642     ASSERT_NE(filePtr, nullptr);
643     dlpLinkManager->dlpLinkFileNameMap_.clear();
644     dlpLinkManager->AddDlpLinkFile(filePtr, "test");
645 
646     DlpCMockCondition condition;
647     condition.mockSequence = { true };
648     SetMockConditions("fuse_reply_err", condition);
649     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
650 
651     DlpCMockCondition condition1;
652     condition1.mockSequence = { true, true, true, true, true };
653     SetMockConditions("fuse_add_direntry", condition1);
654     SetMockCallback("fuse_add_direntry", reinterpret_cast<CommonMockFuncT>(FuseAddDirentryMockTestFileFail));
655     g_fuseReplyErr = 0;
656     FuseDaemon::fuseDaemonOper_.readdir(req, ROOT_INODE, ADD_DIRENTRY_BUFF_LEN, 0, nullptr);
657     EXPECT_EQ(EINVAL, g_fuseReplyErr);
658     CleanMockConditions();
659 
660     dlpLinkManager->DeleteDlpLinkFile(filePtr);
661 }
662 
663 /**
664  * @tc.name: FuseDaemonReadDir005
665  * @tc.desc: test fuse AddDirentry callback test file entry fail
666  * @tc.type: FUNC
667  * @tc.require:AR000GVIGC
668  */
669 HWTEST_F(FuseDaemonTest, FuseDaemonReadDir005, TestSize.Level1)
670 {
671     DLP_LOG_INFO(LABEL, "FuseDaemonReadDir005");
672     fuse_req_t req = nullptr;
673     std::shared_ptr<DlpFile> filePtr = std::make_shared<DlpFile>(-1, DLP_TEST_DIR, 0, false);
674     dlpLinkManager->AddDlpLinkFile(filePtr, "test");
675     DlpCMockCondition condition;
676     condition.mockSequence = { true };
677     SetMockConditions("fuse_reply_err", condition);
678     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
679 
680     DlpCMockCondition condition1;
681     condition1.mockSequence = { true, true, true, true, true };
682     SetMockConditions("fuse_add_direntry", condition1);
683     SetMockCallback("fuse_add_direntry", reinterpret_cast<CommonMockFuncT>(FuseAddDirentryMockTestFileFail));
684 
685     DlpCMockCondition condition2;
686     condition2.mockSequence = { true };
687     SetMockConditions("fuse_reply_buf", condition2);
688     SetMockCallback("fuse_reply_buf", reinterpret_cast<CommonMockFuncT>(FuseReplyBufMock));
689 
690     g_fuseReplyBufSize = 1;
691     FuseDaemon::fuseDaemonOper_.readdir(req, ROOT_INODE, ADD_DIRENTRY_BUFF_LEN, ADD_DIRENTRY_BUFF_LEN + 1, nullptr);
692     EXPECT_EQ(static_cast<size_t>(1), g_fuseReplyBufSize);
693     CleanMockConditions();
694     dlpLinkManager->DeleteDlpLinkFile(filePtr);
695 }
696 
697 /**
698  * @tc.name: FuseDaemonReadDir006
699  * @tc.desc: test fuse AddDirentry callback CUR_DIR entry too large
700  * @tc.type: FUNC
701  * @tc.require:AR000GVIGC
702  */
703 HWTEST_F(FuseDaemonTest, FuseDaemonReadDir006, TestSize.Level1)
704 {
705     DLP_LOG_INFO(LABEL, "FuseDaemonReadDir006");
706     fuse_req_t req = nullptr;
707 
708     DlpCMockCondition condition;
709     condition.mockSequence = { true };
710     SetMockConditions("fuse_reply_err", condition);
711     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
712 
713     DlpCMockCondition condition1;
714     condition1.mockSequence = { true };
715     SetMockConditions("fuse_add_direntry", condition1);
716     SetMockCallback("fuse_add_direntry", reinterpret_cast<CommonMockFuncT>(FuseAddDirentryMockCurDirFail));
717 
718     DlpCMockCondition condition2;
719     condition2.mockSequence = { true };
720     SetMockConditions("fuse_reply_buf", condition2);
721     SetMockCallback("fuse_reply_buf", reinterpret_cast<CommonMockFuncT>(FuseReplyBufMock));
722 
723     g_fuseReplyErr = 0;
724     FuseDaemon::fuseDaemonOper_.readdir(req, ROOT_INODE, ADD_DIRENTRY_BUFF_LEN + 1, DLP_MAX_CONTENT_SIZE, nullptr);
725     EXPECT_EQ(static_cast<size_t>(0), g_fuseReplyBufSize);
726     CleanMockConditions();
727 }
728 
729 /**
730  * @tc.name: FuseDaemonSetAttr001
731  * @tc.desc: test fuse set attr callback abnormal test
732  * @tc.type: FUNC
733  * @tc.require:AR000GVIGC
734  */
735 HWTEST_F(FuseDaemonTest, FuseDaemonSetAttr001, TestSize.Level1)
736 {
737     DLP_LOG_INFO(LABEL, "FuseDaemonReadDir005");
738     fuse_req_t req = nullptr;
739 
740     // attr = nullptr
741     DlpCMockCondition condition;
742     condition.mockSequence = { true };
743     SetMockConditions("fuse_reply_err", condition);
744     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
745     g_fuseReplyErr = 0;
746     FuseDaemon::fuseDaemonOper_.setattr(req, 0, nullptr, 0, nullptr);
747     EXPECT_EQ(EINVAL, g_fuseReplyErr);
748     CleanMockConditions();
749 
750     // ino = ROOT_INODE
751     condition.mockSequence = { true };
752     SetMockConditions("fuse_reply_err", condition);
753     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
754     g_fuseReplyErr = 0;
755     struct stat attr;
756     FuseDaemon::fuseDaemonOper_.setattr(req, ROOT_INODE, &attr, 0, nullptr);
757     EXPECT_EQ(EACCES, g_fuseReplyErr);
758     CleanMockConditions();
759 
760     // ino = 0
761     condition.mockSequence = { true };
762     SetMockConditions("fuse_reply_err", condition);
763     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
764     g_fuseReplyErr = 0;
765     FuseDaemon::fuseDaemonOper_.setattr(req, 0, &attr, 0, nullptr);
766     EXPECT_EQ(ENOENT, g_fuseReplyErr);
767     CleanMockConditions();
768 
769     // truncate fail
770     std::shared_ptr<DlpFile> dlpFile = std::make_shared<DlpFile>(-1, DLP_TEST_DIR, 0, false);
771     ASSERT_NE(dlpFile, nullptr);
772     DlpLinkFile linkfile("test", dlpFile);
773     fuse_ino_t ino = static_cast<fuse_ino_t>(reinterpret_cast<uintptr_t>(&linkfile));
774 
775     condition.mockSequence = { true };
776     SetMockConditions("fuse_reply_err", condition);
777     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
778     g_fuseReplyErr = 0;
779     attr.st_size = 0;
780     FuseDaemon::fuseDaemonOper_.setattr(req, ino, &attr, FUSE_SET_ATTR_SIZE, nullptr);
781     EXPECT_EQ(EINVAL, g_fuseReplyErr);
782     CleanMockConditions();
783 }
784 
785 /**
786  * @tc.name: FuseDaemonSetAttr002
787  * @tc.desc: test fuse set attr callback abnormal test
788  * @tc.type: FUNC
789  * @tc.require:AR000GVIGC
790  */
791 HWTEST_F(FuseDaemonTest, FuseDaemonSetAttr002, TestSize.Level1)
792 {
793     DLP_LOG_INFO(LABEL, "FuseDaemonSetAttr002");
794     fuse_req_t req = nullptr;
795 
796     // attr = nullptr
797     DlpCMockCondition condition;
798 
799     std::shared_ptr<DlpFile> dlpFile = std::make_shared<DlpFile>(-1, DLP_TEST_DIR, 0, false);
800     ASSERT_NE(dlpFile, nullptr);
801     DlpLinkFile linkfile("test", dlpFile);
802     fuse_ino_t ino = static_cast<fuse_ino_t>(reinterpret_cast<uintptr_t>(&linkfile));
803     struct stat attr;
804     g_fuseReplyErr = 0;
805 
806     condition.mockSequence = { true };
807     SetMockConditions("fuse_reply_err", condition);
808     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
809     attr.st_size = DLP_MAX_CONTENT_SIZE + 1;
810     FuseDaemon::fuseDaemonOper_.setattr(req, ino, &attr, FUSE_SET_ATTR_SIZE, nullptr);
811     EXPECT_EQ(EINVAL, g_fuseReplyErr);
812     CleanMockConditions();
813 
814     condition.mockSequence = { true };
815     SetMockConditions("fuse_reply_err", condition);
816     SetMockCallback("fuse_reply_err", reinterpret_cast<CommonMockFuncT>(FuseReplyErrMock));
817     attr.st_size = -1;
818     FuseDaemon::fuseDaemonOper_.setattr(req, ino, &attr, FUSE_SET_ATTR_SIZE, nullptr);
819     EXPECT_EQ(EINVAL, g_fuseReplyErr);
820     CleanMockConditions();
821 }
822 
823 /**
824  * @tc.name: InitFuseFs001
825  * @tc.desc: test fuse daemon init
826  * @tc.type: FUNC
827  * @tc.require:AR000GVIGC
828  */
829 HWTEST_F(FuseDaemonTest, InitFuseFs001, TestSize.Level1)
830 {
831     DLP_LOG_INFO(LABEL, "InitFuseFs001");
832     FuseDaemon::init_ = false;
833     EXPECT_EQ(DLP_PARSE_ERROR_FD_ERROR, FuseDaemon::InitFuseFs());
834     // second init will fail whatever last init result is.
835     EXPECT_EQ(DLP_PARSE_ERROR_FD_ERROR, FuseDaemon::InitFuseFs());
836 
837     // fuse fd is wrong
838     FuseDaemon::init_ = false;
839     EXPECT_EQ(DLP_PARSE_ERROR_FD_ERROR, FuseDaemon::InitFuseFs());
840 }
841 
842 /**
843  * @tc.name: FuseFsDaemonThread001
844  * @tc.desc: test fuse daemon thread abnormal
845  * @tc.type: FUNC
846  * @tc.require:AR000GVIGC
847  */
848 HWTEST_F(FuseDaemonTest, FuseFsDaemonThread001, TestSize.Level1)
849 {
850     DLP_LOG_INFO(LABEL, "FuseFsDaemonThread001");
851 
852     DlpCMockCondition condition;
853     condition.mockSequence = { true };
854     SetMockConditions("fuse_opt_add_arg", condition);
855     DlpCMockCondition condition1;
856     condition1.mockSequence = { true };
857     SetMockConditions("fuse_session_new", condition1);
858     DlpCMockCondition condition2;
859     condition2.mockSequence = { true };
860     SetMockConditions("fuse_opt_free_args", condition2);
861     FuseDaemon::FuseFsDaemonThread(1);
862     EXPECT_EQ(DLP_FUSE_ERROR_OPERATE_FAIL, FuseDaemon::WaitDaemonEnable());
863     CleanMockConditions();
864 }
865 
866 /**
867  * @tc.name: FuseFsDaemonThread002
868  * @tc.desc: test fuse daemon thread abnormal
869  * @tc.type: FUNC
870  * @tc.require:AR000GVIGC
871  */
872 HWTEST_F(FuseDaemonTest, FuseFsDaemonThread002, TestSize.Level1)
873 {
874     DLP_LOG_INFO(LABEL, "FuseFsDaemonThread002");
875 
876     DlpCMockCondition condition;
877     condition.mockSequence = { true };
878     SetMockConditions("fuse_opt_add_arg", condition);
879     DlpCMockCondition condition1;
880     condition1.mockSequence = { true };
881     SetMockConditions("fuse_session_new", condition1);
882     SetMockCallback("fuse_session_new", reinterpret_cast<CommonMockFuncT>(FuseSessionNewMock));
883     DlpCMockCondition condition2;
884     condition2.mockSequence = { true };
885     SetMockConditions("fuse_session_mount", condition2);
886     DlpCMockCondition condition3;
887     condition3.mockSequence = { true };
888     SetMockConditions("fuse_session_destroy", condition3);
889     DlpCMockCondition condition4;
890     condition4.mockSequence = { true };
891     SetMockConditions("fuse_opt_free_args", condition4);
892 
893     FuseDaemon::FuseFsDaemonThread(1);
894     EXPECT_EQ(DLP_FUSE_ERROR_OPERATE_FAIL, FuseDaemon::WaitDaemonEnable());
895     CleanMockConditions();
896 }
897 
898 /**
899  * @tc.name: FuseFsDaemonThread003
900  * @tc.desc: test fuse daemon thread abnormal
901  * @tc.type: FUNC
902  * @tc.require:AR000GVIGC
903  */
904 HWTEST_F(FuseDaemonTest, FuseFsDaemonThread003, TestSize.Level1)
905 {
906     DLP_LOG_INFO(LABEL, "FuseFsDaemonThread003");
907 
908     DlpCMockCondition condition;
909     condition.mockSequence = { true };
910     SetMockConditions("fuse_opt_add_arg", condition);
911     DlpCMockCondition condition1;
912     condition1.mockSequence = { true };
913     SetMockConditions("fuse_session_new", condition1);
914     SetMockCallback("fuse_session_new", reinterpret_cast<CommonMockFuncT>(FuseSessionNewMock));
915     DlpCMockCondition condition2;
916     condition2.mockSequence = { true };
917     SetMockConditions("fuse_session_mount", condition2);
918     SetMockCallback("fuse_session_mount", reinterpret_cast<CommonMockFuncT>(FuseSessionMountMock));
919     DlpCMockCondition condition3;
920     condition3.mockSequence = { true };
921     SetMockConditions("fuse_session_destroy", condition3);
922     DlpCMockCondition condition4;
923     condition4.mockSequence = { true };
924     SetMockConditions("fuse_opt_free_args", condition4);
925     DlpCMockCondition condition5;
926     condition5.mockSequence = { true };
927     SetMockConditions("fuse_session_loop", condition5);
928 
929     FuseDaemon::FuseFsDaemonThread(1);
930     EXPECT_EQ(0, FuseDaemon::WaitDaemonEnable());
931     CleanMockConditions();
932 }
933 
934 /**
935  * @tc.name: FuseDaemonInit001
936  * @tc.desc: FuseDaemonInit
937  * @tc.type: FUNC
938  * @tc.require:AR000GVIGC
939  */
940 HWTEST_F(FuseDaemonTest, FuseDaemonInit001, TestSize.Level1)
941 {
942     DLP_LOG_INFO(LABEL, "FuseDaemonInit001");
943 
944     FuseDaemon::fuseDaemonOper_.init(nullptr, nullptr);
945 
946     fuse_conn_info conn = { 0 };
947     FuseDaemon::fuseDaemonOper_.init(nullptr, &conn);
948     EXPECT_EQ(FUSE_CAP_WRITEBACK_CACHE, conn.want);
949 }
950 }  // namespace DlpPermission
951 }  // namespace Security
952 }  // namespace OHOS