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 <dirent.h>
22#include <fcntl.h>
23#include <unistd.h>
24#include <arpa/inet.h>
25#include <gtest/gtest.h>
26#include <netinet/in.h>
27#include <sys/stat.h>
28#include <sys/socket.h>
29#include <sys/types.h>
30
31
32using namespace testing::ext;
33
34class HatsUtimensatTest : public testing::Test {
35public:
36static void SetUpTestCase();
37static void TearDownTestCase();
38void SetUp();
39void TearDown();
40private:
41};
42void HatsUtimensatTest::SetUp()
43{
44}
45void HatsUtimensatTest::TearDown()
46{
47}
48void HatsUtimensatTest::SetUpTestCase()
49{
50}
51void HatsUtimensatTest::TearDownTestCase()
52{
53}
54
55static const char *UTIMENSAT_TEST_FILE = "/data/local/tmp/tryUtimensat.txt";
56static const int ACCESS_TIME_SEC = 10;
57static const int ACCESS_TIME_NSEC = 0;
58static const int MODIFICATION_TIME_SEC = 11;
59static const int MODIFICATION_TIME_NSEC = 0;
60
61/*
62 * @tc.number : SUB_KERNEL_SYSCALL_UTIMENSAT_0100
63 * @tc.name   : UtimensatChangeFileTimeSuccess_0001
64 * @tc.desc   : utimensat change file access time and modification time success.
65 * @tc.size   : MediumTest
66 * @tc.type   : Function
67 * @tc.level  : Level 1
68 */
69HWTEST_F(HatsUtimensatTest, UtimensatChangeFileTimeSuccess_0001, Function | MediumTest | Level1)
70{
71    int ret;
72    int fd;
73    struct timespec newTime[2];
74    struct stat fileStat1;
75    struct stat fileStat2;
76
77    fd = open(UTIMENSAT_TEST_FILE, O_RDONLY);
78    if (fd != -1) {
79        ret = remove(UTIMENSAT_TEST_FILE);
80        EXPECT_TRUE(ret == 0);
81    }
82    close(fd);
83
84    fd = open(UTIMENSAT_TEST_FILE, O_RDONLY | O_CREAT | O_TRUNC, 0644);
85    EXPECT_TRUE(fd >= 3);
86    close(fd);
87
88    ret = stat(UTIMENSAT_TEST_FILE, &fileStat1);
89    EXPECT_TRUE(ret == 0);
90
91    //access time
92    newTime[0].tv_sec = ACCESS_TIME_SEC;
93    newTime[0].tv_nsec = ACCESS_TIME_NSEC;
94    //modification time
95    newTime[1].tv_sec = MODIFICATION_TIME_SEC;
96    newTime[1].tv_nsec = MODIFICATION_TIME_NSEC;
97
98    ret = utimensat(AT_FDCWD, UTIMENSAT_TEST_FILE, newTime, 0);
99    EXPECT_TRUE(ret == 0);
100
101    ret = stat(UTIMENSAT_TEST_FILE, &fileStat2);
102    EXPECT_TRUE(ret == 0);
103
104    ret = (fileStat1.st_atime != fileStat2.st_atime);
105    EXPECT_TRUE(ret == 1);
106    ret = (fileStat1.st_mtime != fileStat2.st_mtime);
107    EXPECT_TRUE(ret == 1);
108}
109
110/*
111 * @tc.number : SUB_KERNEL_SYSCALL_UTIMENSAT_0200
112 * @tc.name   : UtimensatInvalidTimeFail_0002
113 * @tc.desc   : utimensat set time using invalid time value fail.
114 * @tc.size   : MediumTest
115 * @tc.type   : Function
116 * @tc.level  : Level 2
117 */
118HWTEST_F(HatsUtimensatTest, UtimensatInvalidTimeFail_0002, Function | MediumTest | Level2)
119{
120    int ret;
121    int fd;
122    struct timespec newTime[2];
123    struct stat fileStat1;
124
125    fd = open(UTIMENSAT_TEST_FILE, O_RDONLY);
126    if (fd != -1) {
127        ret = remove(UTIMENSAT_TEST_FILE);
128        EXPECT_TRUE(ret == 0);
129    }
130    close(fd);
131
132    fd = open(UTIMENSAT_TEST_FILE, O_RDONLY | O_CREAT | O_TRUNC, 0644);
133    EXPECT_TRUE(fd >= 3);
134    close(fd);
135
136    ret = stat(UTIMENSAT_TEST_FILE, &fileStat1);
137    EXPECT_TRUE(ret == 0);
138
139    //access time
140    newTime[0].tv_sec = -1;
141    newTime[0].tv_nsec = -1;
142    //modification time
143    newTime[1].tv_sec = -1;
144    newTime[1].tv_nsec = -1;
145
146    errno = 0;
147    ret = utimensat(AT_FDCWD, UTIMENSAT_TEST_FILE, newTime, 0);
148    EXPECT_TRUE(ret == -1);
149    EXPECT_EQ(errno, EINVAL);
150}
151
152/*
153 * @tc.number : SUB_KERNEL_SYSCALL_UTIMENSAT_0300
154 * @tc.name   : UtimensatSetTimeOfNonexistFileFail_0003
155 * @tc.desc   : utimensat set time of a non-exist file fail.
156 * @tc.size   : MediumTest
157 * @tc.type   : Function
158 * @tc.level  : Level 2
159 */
160HWTEST_F(HatsUtimensatTest, UtimensatSetTimeOfNonexistFileFail_0003, Function | MediumTest | Level2)
161{
162    int ret;
163    int fd;
164    struct timespec newTime[2];
165
166    fd = open(UTIMENSAT_TEST_FILE, O_RDONLY);
167    if (fd != -1) {
168        ret = remove(UTIMENSAT_TEST_FILE);
169        EXPECT_TRUE(ret == 0);
170    }
171    close(fd);
172
173    //access time
174    newTime[0].tv_sec = ACCESS_TIME_SEC;
175    newTime[0].tv_nsec = ACCESS_TIME_NSEC;
176    //modification time
177    newTime[1].tv_sec = MODIFICATION_TIME_SEC;
178    newTime[1].tv_nsec = MODIFICATION_TIME_NSEC;
179
180    errno = 0;
181    ret = utimensat(AT_FDCWD, UTIMENSAT_TEST_FILE, newTime, 0);
182    EXPECT_TRUE(ret == -1);
183    EXPECT_EQ(errno, ENOENT);
184}
185
186/*
187 * @tc.number : SUB_KERNEL_SYSCALL_UTIMENSAT_0400
188 * @tc.name   : UtimensatInvalidFlagFail_0004
189 * @tc.desc   : utimensat change time with invalid flag fail.
190 * @tc.size   : MediumTest
191 * @tc.type   : Function
192 * @tc.level  : Level 2
193 */
194HWTEST_F(HatsUtimensatTest, UtimensatInvalidFlagFail_0004, Function | MediumTest | Level2)
195{
196    int ret;
197    int fd;
198    struct timespec newTime[2];
199
200    fd = open(UTIMENSAT_TEST_FILE, O_RDONLY);
201    if (fd != -1) {
202        ret = remove(UTIMENSAT_TEST_FILE);
203        EXPECT_TRUE(ret == 0);
204    }
205    close(fd);
206
207    fd = open(UTIMENSAT_TEST_FILE, O_RDONLY | O_CREAT | O_TRUNC, 0644);
208    EXPECT_TRUE(fd >= 3);
209    close(fd);
210
211    //access time
212    newTime[0].tv_sec = ACCESS_TIME_SEC;
213    newTime[0].tv_nsec = ACCESS_TIME_NSEC;
214    //modification time
215    newTime[1].tv_sec = MODIFICATION_TIME_SEC;
216    newTime[1].tv_nsec = MODIFICATION_TIME_NSEC;
217
218    errno = 0;
219    ret = utimensat(AT_FDCWD, UTIMENSAT_TEST_FILE, newTime, -1);
220    EXPECT_TRUE(ret == -1);
221    EXPECT_EQ(errno, EINVAL);
222}
223