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 <cerrno>
17#include <cstdio>
18#include <cstdlib>
19#include <string>
20#include <vector>
21#include <fcntl.h>
22#include <unistd.h>
23#include <gtest/gtest.h>
24#include <sys/file.h>
25#include <sys/stat.h>
26#include <sys/types.h>
27#include <sys/xattr.h>
28#include "securec.h"
29
30using namespace testing::ext;
31using namespace std;
32
33static const int BUFFER_SIZE = 128;
34static const char *TEST_FILE = "/data/local/tmp/fsetxattr.txt";
35mode_t MODE_0644 = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
36static const char *XATTR_NAME = "user.author";
37static const char *AUTHOR_NAME = "sun";
38static const char *AUTHOR_NAME_NEW = "bin";
39size_t g_length = strlen(AUTHOR_NAME) + 1;
40
41class FsetxattrApiTest : public testing::Test {
42public:
43    static void SetUpTestCase();
44    static void TearDownTestCase();
45    void SetUp();
46    void TearDown();
47private:
48};
49void FsetxattrApiTest::SetUp()
50{
51}
52void FsetxattrApiTest::TearDown()
53{
54}
55void FsetxattrApiTest::SetUpTestCase()
56{
57}
58void FsetxattrApiTest::TearDownTestCase()
59{
60}
61
62/*
63 * @tc.number : SUB_KERNEL_SYSCALL_FSETXATTR_0100
64 * @tc.name   : FsetxattrValidFdAttrSuccess_0001
65 * @tc.desc   : fsetxattr set valid file attribute success.
66 * @tc.size   : MediumTest
67 * @tc.type   : Function
68 * @tc.level  : Level 1
69 */
70HWTEST_F(FsetxattrApiTest, FsetxattrValidFdAttrSuccess_0001, Function | MediumTest | Level1)
71{
72    ssize_t ret = -1;
73    char buf[BUFFER_SIZE] = {0};
74    int fd = open(TEST_FILE, O_RDWR | O_CREAT, MODE_0644);
75    EXPECT_TRUE(fd > 0);
76
77    ret = fsetxattr(fd, XATTR_NAME, AUTHOR_NAME, g_length, 0);
78    EXPECT_EQ(ret, 0);
79    ret = fgetxattr(fd, XATTR_NAME, buf, g_length);
80    EXPECT_EQ(ret, g_length);
81    EXPECT_STREQ(buf, AUTHOR_NAME);
82
83    close(fd);
84    remove(TEST_FILE);
85}
86
87/*
88 * @tc.number : SUB_KERNEL_SYSCALL_FSETXATTR_0200
89 * @tc.name   : FsetxattrInvalidFdAttrFail_0002
90 * @tc.desc   : fsetxattr set invalid file attribute fail, errno EBADF.
91 * @tc.size   : MediumTest
92 * @tc.type   : Function
93 * @tc.level  : Level 2
94 */
95HWTEST_F(FsetxattrApiTest, FsetxattrInvalidFdAttrFail_0002, Function | MediumTest | Level2)
96{
97    ssize_t ret = -1;
98    int invalidFd = -1;
99
100    errno = 0;
101    ret = fsetxattr(invalidFd, XATTR_NAME, AUTHOR_NAME, g_length, 0);
102    EXPECT_EQ(ret, -1);
103    EXPECT_EQ(errno, EBADF);
104}
105
106/*
107 * @tc.number : SUB_KERNEL_SYSCALL_FSETXATTR_0300
108 * @tc.name   : FsetxattrSetTwiceAttrFail_0003
109 * @tc.desc   : fsetxattr set the file attribute twice fail.
110 * @tc.size   : MediumTest
111 * @tc.type   : Function
112 * @tc.level  : Level 2
113 */
114HWTEST_F(FsetxattrApiTest, FsetxattrSetTwiceAttrFail_0003, Function | MediumTest | Level2)
115{
116    ssize_t ret = -1;
117    char buf[BUFFER_SIZE] = {0};
118    int fd = open(TEST_FILE, O_RDWR | O_CREAT, MODE_0644);
119    EXPECT_TRUE(fd > 0);
120
121    ret = fsetxattr(fd, XATTR_NAME, AUTHOR_NAME, g_length, 0);
122    EXPECT_EQ(ret, 0);
123    errno = 0;
124    ret = fsetxattr(fd, XATTR_NAME, AUTHOR_NAME_NEW, g_length, XATTR_CREATE);
125    EXPECT_EQ(ret, -1);
126    EXPECT_EQ(errno, EEXIST);
127    ret = fgetxattr(fd, XATTR_NAME, buf, g_length);
128    EXPECT_EQ(ret, g_length);
129    EXPECT_STREQ(buf, AUTHOR_NAME);
130
131    close(fd);
132    remove(TEST_FILE);
133}
134
135/*
136 * @tc.number : SUB_KERNEL_SYSCALL_FSETXATTR_0400
137 * @tc.name   : FsetxattrSetShortAttrFail_0004
138 * @tc.desc   : fsetxattr set file attribute return success but length is shorter than real and finally unexpected.
139 * @tc.size   : MediumTest
140 * @tc.type   : Function
141 * @tc.level  : Level 2
142 */
143HWTEST_F(FsetxattrApiTest, FsetxattrSetShortAttrFail_0004, Function | MediumTest | Level2)
144{
145    ssize_t ret = -1;
146    char buf[BUFFER_SIZE] = {0};
147    int fd = open(TEST_FILE, O_RDWR | O_CREAT, MODE_0644);
148    EXPECT_TRUE(fd > 0);
149
150    ret = fsetxattr(fd, XATTR_NAME, AUTHOR_NAME, 0, 0);
151    EXPECT_EQ(ret, 0);
152
153    ret = fgetxattr(fd, XATTR_NAME, buf, g_length);
154    EXPECT_NE(ret, g_length);
155    EXPECT_STRNE(buf, AUTHOR_NAME);
156
157    close(fd);
158    remove(TEST_FILE);
159}
160
161/*
162 * @tc.number : SUB_KERNEL_SYSCALL_FSETXATTR_0500
163 * @tc.name   : FsetxattrReplaceNonExistAttrFail_0005
164 * @tc.desc   : fsetxattr replace file non-exist attribute fail, errno ENODATA.
165 * @tc.size   : MediumTest
166 * @tc.type   : Function
167 * @tc.level  : Level 2
168 */
169HWTEST_F(FsetxattrApiTest, FsetxattrReplaceNonExistAttrFail_0005, Function | MediumTest | Level2)
170{
171    ssize_t ret = -1;
172    int fd = open(TEST_FILE, O_RDWR | O_CREAT, MODE_0644);
173    EXPECT_TRUE(fd > 0);
174
175    errno = 0;
176    ret = fsetxattr(fd, XATTR_NAME, AUTHOR_NAME, g_length, XATTR_REPLACE);
177    EXPECT_EQ(ret, -1);
178    EXPECT_EQ(errno, ENODATA);
179
180    close(fd);
181    remove(TEST_FILE);
182}
183
184/*
185 * @tc.number : SUB_KERNEL_SYSCALL_FSETXATTR_0600
186 * @tc.name   : FsetxattrSetUnsupportAttrFail_0006
187 * @tc.desc   : fsetxattr set file unsupported attribute fail, errno ENOTSUP.
188 * @tc.size   : MediumTest
189 * @tc.type   : Function
190 * @tc.level  : Level 2
191 */
192HWTEST_F(FsetxattrApiTest, FsetxattrSetUnsupportAttrFail_0006, Function | MediumTest | Level2)
193{
194    ssize_t ret = -1;
195    int fd = open(TEST_FILE, O_RDWR | O_CREAT, MODE_0644);
196    EXPECT_TRUE(fd > 0);
197
198    errno = 0;
199    ret = fsetxattr(fd, "invalid_attr", AUTHOR_NAME, g_length, 0);
200    EXPECT_EQ(ret, -1);
201    EXPECT_EQ(errno, ENOTSUP);
202
203    close(fd);
204    remove(TEST_FILE);
205}
206