1/*
2 * Copyright (C) 2024 HiHope Open Source Organization.
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 <cstdio>
17#include <cstdlib>
18#include <fcntl.h>
19#include <string>
20#include <unistd.h>
21#include <vector>
22#include <gtest/gtest.h>
23#include <sys/stat.h>
24#include <sys/types.h>
25#include <sys/xattr.h>
26#include "securec.h"
27
28using namespace testing::ext;
29using namespace std;
30
31static const char *TEST_DIR = "/data/local/tmp";
32static const char *OLD_FILE_NAME = "/data/local/tmp/old_file";
33static const char *NEW_FILE_NAME = "/data/local/tmp/new_link";
34static const char *INVALID_FILE_NAME = "/data/local/tmp/invalid";
35
36class LinkatApiTest : public testing::Test {
37public:
38    static void SetUpTestCase();
39    static void TearDownTestCase();
40    void SetUp();
41    void TearDown();
42private:
43};
44void LinkatApiTest::SetUp()
45{
46}
47void LinkatApiTest::TearDown()
48{
49}
50void LinkatApiTest::SetUpTestCase()
51{
52}
53void LinkatApiTest::TearDownTestCase()
54{
55}
56
57/*
58 * @tc.number : SUB_KERNEL_SYSCALL_LINKAT_0100
59 * @tc.name   : LinkatCreateHardLinkSuccess_0001
60 * @tc.desc   : linkat create hard link success.
61 * @tc.size   : MediumTest
62 * @tc.type   : Function
63 * @tc.level  : Level 1
64 */
65HWTEST_F(LinkatApiTest, LinkatCreateHardLinkSuccess_0001, Function | MediumTest | Level1)
66{
67    int ret;
68    int dirFd;
69    dirFd = open(TEST_DIR, O_DIRECTORY);
70    EXPECT_GE(dirFd, 0);
71    int fd = open(OLD_FILE_NAME, O_CREAT | O_RDWR, 0644);
72    close(fd);
73
74    ret = linkat(dirFd, OLD_FILE_NAME, dirFd, NEW_FILE_NAME, 0);
75    EXPECT_GE(ret, 0);
76
77    close(dirFd);
78    unlink(NEW_FILE_NAME);
79    unlink(OLD_FILE_NAME);
80}
81
82/*
83 * @tc.number : SUB_KERNEL_SYSCALL_LINKAT_0200
84 * @tc.name   : LinkatInvalidFlagFailed_0002
85 * @tc.desc   : linkat invalid flag failed errno EINVAL.
86 * @tc.size   : MediumTest
87 * @tc.type   : Function
88 * @tc.level  : Level 2
89 */
90HWTEST_F(LinkatApiTest, LinkatInvalidFdFailed_0002, Function | MediumTest | Level2)
91{
92    int ret;
93    int fd = open(OLD_FILE_NAME, O_CREAT | O_RDWR, 0644);
94    close(fd);
95
96    errno = 0;
97    ret = linkat(0, OLD_FILE_NAME, 0, NEW_FILE_NAME, -1);
98    EXPECT_EQ(ret, -1);
99    EXPECT_EQ(errno, EINVAL);
100
101    unlink(NEW_FILE_NAME);
102    unlink(OLD_FILE_NAME);
103}
104
105/*
106 * @tc.number : SUB_KERNEL_SYSCALL_LINKAT_0300
107 * @tc.name   : LinkatInvalidPathFailed_0003
108 * @tc.desc   : linkat invalid path failed errno ENOENT.
109 * @tc.size   : MediumTest
110 * @tc.type   : Function
111 * @tc.level  : Level 2
112 */
113HWTEST_F(LinkatApiTest, LinkatInvalidPathFailed_0003, Function | MediumTest | Level2)
114{
115    int ret;
116    int dirFd;
117    dirFd = open(TEST_DIR, O_DIRECTORY);
118    EXPECT_GE(dirFd, 0);
119    int fd = open(OLD_FILE_NAME, O_CREAT | O_RDWR, 0644);
120    close(fd);
121
122    ret = linkat(dirFd, INVALID_FILE_NAME, dirFd, NEW_FILE_NAME, 0);
123    EXPECT_EQ(ret, -1);
124    EXPECT_EQ(errno, ENOENT);
125
126    close(dirFd);
127    unlink(NEW_FILE_NAME);
128    unlink(OLD_FILE_NAME);
129}
130
131/*
132 * @tc.number : SUB_KERNEL_SYSCALL_LINKAT_0400
133 * @tc.name   : LinkatAT_SYMLINK_FOLLOWFlagSuccess_0004
134 * @tc.desc   : linkat AT_SYMLINK_FOLLOW flag test success.
135 * @tc.size   : MediumTest
136 * @tc.type   : Function
137 * @tc.level  : Level 1
138 */
139HWTEST_F(LinkatApiTest, LinkatAT_SYMLINK_FOLLOWFlagSuccess_0004, Function | MediumTest | Level1)
140{
141    int ret;
142    int dirFd;
143    dirFd = open(TEST_DIR, O_DIRECTORY);
144    EXPECT_GE(dirFd, 0);
145    int fd = open(OLD_FILE_NAME, O_CREAT | O_RDWR, 0644);
146    close(fd);
147
148    ret = linkat(dirFd, OLD_FILE_NAME, dirFd, NEW_FILE_NAME, AT_SYMLINK_FOLLOW);
149    EXPECT_GE(ret, 0);
150
151    close(dirFd);
152    unlink(NEW_FILE_NAME);
153    unlink(OLD_FILE_NAME);
154}