1 //===-- Unittests for target platform file implementation -----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "src/__support/File/file.h"
10 #include "utils/UnitTest/Test.h"
11
12 #include <stdio.h> // For SEEK_* macros
13
14 using File = __llvm_libc::File;
15 constexpr char TEXT[] = "Hello, File";
16 constexpr size_t TEXT_SIZE = sizeof(TEXT) - 1; // Ignore the null terminator
17
TEST(LlvmLibcPlatformFileTest,CreateWriteCloseAndReadBack)18 TEST(LlvmLibcPlatformFileTest, CreateWriteCloseAndReadBack) {
19 constexpr char FILENAME[] = "testdata/create_write_close_and_readback.test";
20 File *file = __llvm_libc::openfile(FILENAME, "w");
21 ASSERT_FALSE(file == nullptr);
22 ASSERT_EQ(file->write(TEXT, TEXT_SIZE), TEXT_SIZE);
23 ASSERT_EQ(file->close(), 0);
24
25 file = __llvm_libc::openfile(FILENAME, "r");
26 ASSERT_FALSE(file == nullptr);
27 char data[sizeof(TEXT)];
28 ASSERT_EQ(file->read(data, TEXT_SIZE), TEXT_SIZE);
29 data[TEXT_SIZE] = '\0';
30 ASSERT_STREQ(data, TEXT);
31
32 // Reading more data should trigger EOF.
33 ASSERT_EQ(file->read(data, TEXT_SIZE), size_t(0));
34 ASSERT_TRUE(file->iseof());
35
36 ASSERT_EQ(file->close(), 0);
37 }
38
TEST(LlvmLibcPlatformFileTest,CreateWriteSeekAndReadBack)39 TEST(LlvmLibcPlatformFileTest, CreateWriteSeekAndReadBack) {
40 constexpr char FILENAME[] = "testdata/create_write_seek_and_readback.test";
41 File *file = __llvm_libc::openfile(FILENAME, "w+");
42 ASSERT_FALSE(file == nullptr);
43 ASSERT_EQ(file->write(TEXT, TEXT_SIZE), TEXT_SIZE);
44
45 ASSERT_EQ(file->seek(0, SEEK_SET), 0);
46
47 char data[sizeof(TEXT)];
48 ASSERT_EQ(file->read(data, TEXT_SIZE), TEXT_SIZE);
49 data[TEXT_SIZE] = '\0';
50 ASSERT_STREQ(data, TEXT);
51
52 // Reading more data should trigger EOF.
53 ASSERT_EQ(file->read(data, TEXT_SIZE), size_t(0));
54 ASSERT_TRUE(file->iseof());
55
56 ASSERT_EQ(file->close(), 0);
57 }
58
TEST(LlvmLibcPlatformFileTest,CreateAppendCloseAndReadBack)59 TEST(LlvmLibcPlatformFileTest, CreateAppendCloseAndReadBack) {
60 constexpr char FILENAME[] = "testdata/create_append_close_and_readback.test";
61 File *file = __llvm_libc::openfile(FILENAME, "w");
62 ASSERT_FALSE(file == nullptr);
63 ASSERT_EQ(file->write(TEXT, TEXT_SIZE), TEXT_SIZE);
64 ASSERT_EQ(file->close(), 0);
65
66 file = __llvm_libc::openfile(FILENAME, "a");
67 ASSERT_FALSE(file == nullptr);
68 constexpr char APPEND_TEXT[] = " Append Text";
69 constexpr size_t APPEND_TEXT_SIZE = sizeof(APPEND_TEXT) - 1;
70 ASSERT_EQ(file->write(APPEND_TEXT, APPEND_TEXT_SIZE), APPEND_TEXT_SIZE);
71 ASSERT_EQ(file->close(), 0);
72
73 file = __llvm_libc::openfile(FILENAME, "r");
74 ASSERT_FALSE(file == nullptr);
75 constexpr size_t READ_SIZE = TEXT_SIZE + APPEND_TEXT_SIZE;
76 char data[READ_SIZE + 1];
77 ASSERT_EQ(file->read(data, READ_SIZE), READ_SIZE);
78 data[READ_SIZE] = '\0';
79 ASSERT_STREQ(data, "Hello, File Append Text");
80
81 // Reading more data should trigger EOF.
82 ASSERT_EQ(file->read(data, READ_SIZE), size_t(0));
83 ASSERT_TRUE(file->iseof());
84
85 ASSERT_EQ(file->close(), 0);
86 }
87
TEST(LlvmLibcPlatformFileTest,CreateAppendSeekAndReadBack)88 TEST(LlvmLibcPlatformFileTest, CreateAppendSeekAndReadBack) {
89 constexpr char FILENAME[] = "testdata/create_append_seek_and_readback.test";
90 File *file = __llvm_libc::openfile(FILENAME, "w");
91 ASSERT_FALSE(file == nullptr);
92 ASSERT_EQ(file->write(TEXT, TEXT_SIZE), TEXT_SIZE);
93 ASSERT_EQ(file->close(), 0);
94
95 file = __llvm_libc::openfile(FILENAME, "a+");
96 ASSERT_FALSE(file == nullptr);
97 constexpr char APPEND_TEXT[] = " Append Text";
98 constexpr size_t APPEND_TEXT_SIZE = sizeof(APPEND_TEXT) - 1;
99 ASSERT_EQ(file->write(APPEND_TEXT, APPEND_TEXT_SIZE), APPEND_TEXT_SIZE);
100
101 ASSERT_EQ(file->seek(-APPEND_TEXT_SIZE, SEEK_END), 0);
102 char data[APPEND_TEXT_SIZE + 1];
103 ASSERT_EQ(file->read(data, APPEND_TEXT_SIZE), APPEND_TEXT_SIZE);
104 data[APPEND_TEXT_SIZE] = '\0';
105 ASSERT_STREQ(data, APPEND_TEXT);
106
107 // Reading more data should trigger EOF.
108 ASSERT_EQ(file->read(data, APPEND_TEXT_SIZE), size_t(0));
109 ASSERT_TRUE(file->iseof());
110
111 ASSERT_EQ(file->close(), 0);
112 }
113
TEST(LlvmLibcPlatformFileTest,LargeFile)114 TEST(LlvmLibcPlatformFileTest, LargeFile) {
115 constexpr size_t DATA_SIZE = File::DEFAULT_BUFFER_SIZE >> 2;
116 constexpr char BYTE = 123;
117 char write_data[DATA_SIZE];
118 for (size_t i = 0; i < DATA_SIZE; ++i)
119 write_data[i] = BYTE;
120
121 constexpr char FILENAME[] = "testdata/large_file.test";
122 File *file = __llvm_libc::openfile(FILENAME, "w");
123 ASSERT_FALSE(file == nullptr);
124
125 constexpr int REPEAT = 5;
126 for (int i = 0; i < REPEAT; ++i) {
127 ASSERT_EQ(file->write(write_data, DATA_SIZE), DATA_SIZE);
128 }
129 ASSERT_EQ(file->close(), 0);
130
131 file = __llvm_libc::openfile(FILENAME, "r");
132 ASSERT_FALSE(file == nullptr);
133 constexpr size_t READ_SIZE = DATA_SIZE * REPEAT;
134 char data[READ_SIZE] = {0};
135 ASSERT_EQ(file->read(data, READ_SIZE), READ_SIZE);
136
137 for (size_t i = 0; i < READ_SIZE; ++i)
138 ASSERT_EQ(data[i], BYTE);
139
140 // Reading more data should trigger EOF.
141 ASSERT_EQ(file->read(data, 1), size_t(0));
142 ASSERT_TRUE(file->iseof());
143
144 ASSERT_EQ(file->close(), 0);
145 }
146
TEST(LlvmLibcPlatformFileTest,ReadSeekCurAndRead)147 TEST(LlvmLibcPlatformFileTest, ReadSeekCurAndRead) {
148 constexpr char FILENAME[] = "testdata/read_seek_cur_and_read.test";
149 File *file = __llvm_libc::openfile(FILENAME, "w");
150 ASSERT_FALSE(file == nullptr);
151 constexpr char CONTENT[] = "1234567890987654321";
152 ASSERT_EQ(sizeof(CONTENT) - 1, file->write(CONTENT, sizeof(CONTENT) - 1));
153 ASSERT_EQ(0, file->close());
154
155 file = __llvm_libc::openfile(FILENAME, "r");
156 ASSERT_FALSE(file == nullptr);
157
158 constexpr size_t READ_SIZE = 5;
159 char data[READ_SIZE];
160 data[READ_SIZE - 1] = '\0';
161 ASSERT_EQ(file->read(data, READ_SIZE - 1), READ_SIZE - 1);
162 ASSERT_STREQ(data, "1234");
163 ASSERT_EQ(file->seek(5, SEEK_CUR), 0);
164 ASSERT_EQ(file->read(data, READ_SIZE - 1), READ_SIZE - 1);
165 ASSERT_STREQ(data, "0987");
166 ASSERT_EQ(file->seek(-5, SEEK_CUR), 0);
167 ASSERT_EQ(file->read(data, READ_SIZE - 1), READ_SIZE - 1);
168 ASSERT_STREQ(data, "9098");
169
170 ASSERT_EQ(file->close(), 0);
171 }
172
TEST(LlvmLibcPlatformFileTest,IncorrectOperation)173 TEST(LlvmLibcPlatformFileTest, IncorrectOperation) {
174 constexpr char FILENAME[] = "testdata/incorrect_operation.test";
175 char data[1] = {123};
176
177 File *file = __llvm_libc::openfile(FILENAME, "w");
178 ASSERT_FALSE(file == nullptr);
179 ASSERT_EQ(file->read(data, 1), size_t(0)); // Cannot read
180 ASSERT_FALSE(file->iseof());
181 ASSERT_TRUE(file->error());
182 ASSERT_EQ(file->close(), 0);
183
184 file = __llvm_libc::openfile(FILENAME, "r");
185 ASSERT_FALSE(file == nullptr);
186 ASSERT_EQ(file->write(data, 1), size_t(0)); // Cannot write
187 ASSERT_FALSE(file->iseof());
188 ASSERT_TRUE(file->error());
189 ASSERT_EQ(file->close(), 0);
190
191 file = __llvm_libc::openfile(FILENAME, "a");
192 ASSERT_FALSE(file == nullptr);
193 ASSERT_EQ(file->read(data, 1), size_t(0)); // Cannot read
194 ASSERT_FALSE(file->iseof());
195 ASSERT_TRUE(file->error());
196 ASSERT_EQ(file->close(), 0);
197 }
198
TEST(LlvmLibcPlatformFileTest,StdOutStdErrSmokeTest)199 TEST(LlvmLibcPlatformFileTest, StdOutStdErrSmokeTest) {
200 EXPECT_FALSE(__llvm_libc::stdout == nullptr);
201 EXPECT_FALSE(__llvm_libc::stderr == nullptr);
202 }
203