1 /*
2  * Copyright (c) 2018 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include <fcntl.h>
9 #include <posix/unistd.h>
10 #include "test_fs.h"
11 
12 const char test_str[] = "hello world!";
13 int file;
14 
test_file_open(void)15 static int test_file_open(void)
16 {
17 	int res;
18 
19 	res = open(TEST_FILE, O_CREAT | O_RDWR);
20 
21 	zassert_true(res >= 0, "Failed opening file: %d, errno=%d\n", res, errno);
22 
23 	file = res;
24 
25 	return TC_PASS;
26 }
27 
test_file_write(void)28 int test_file_write(void)
29 {
30 	ssize_t brw;
31 	off_t res;
32 
33 	res = lseek(file, 0, SEEK_SET);
34 	if (res != 0) {
35 		TC_PRINT("lseek failed [%d]\n", (int)res);
36 		close(file);
37 		return TC_FAIL;
38 	}
39 
40 	brw = write(file, (char *)test_str, strlen(test_str));
41 	if (brw < 0) {
42 		TC_PRINT("Failed writing to file [%d]\n", (int)brw);
43 		close(file);
44 		return TC_FAIL;
45 	}
46 
47 	if (brw < strlen(test_str)) {
48 		TC_PRINT("Unable to complete write. Volume full.\n");
49 		TC_PRINT("Number of bytes written: [%d]\n", (int)brw);
50 		close(file);
51 		return TC_FAIL;
52 	}
53 
54 	return res;
55 }
56 
test_file_read(void)57 static int test_file_read(void)
58 {
59 	ssize_t brw;
60 	off_t res;
61 	char read_buff[80];
62 	size_t sz = strlen(test_str);
63 
64 	res = lseek(file, 0, SEEK_SET);
65 	if (res != 0) {
66 		TC_PRINT("lseek failed [%d]\n", (int)res);
67 		close(file);
68 		return TC_FAIL;
69 	}
70 
71 	brw = read(file, read_buff, sz);
72 	if (brw < 0) {
73 		TC_PRINT("Failed reading file [%d]\n", (int)brw);
74 		close(file);
75 		return TC_FAIL;
76 	}
77 
78 	read_buff[brw] = 0;
79 
80 	if (strcmp(test_str, read_buff)) {
81 		TC_PRINT("Error - Data read does not match data written\n");
82 		TC_PRINT("Data read:\"%s\"\n\n", read_buff);
83 		return TC_FAIL;
84 	}
85 
86 	/* Now test after non-zero lseek. */
87 
88 	res = lseek(file, 2, SEEK_SET);
89 	if (res != 2) {
90 		TC_PRINT("lseek failed [%d]\n", (int)res);
91 		close(file);
92 		return TC_FAIL;
93 	}
94 
95 	brw = read(file, read_buff, sizeof(read_buff));
96 	if (brw < 0) {
97 		TC_PRINT("Failed reading file [%d]\n", (int)brw);
98 		close(file);
99 		return TC_FAIL;
100 	}
101 
102 	/* Check for array overrun */
103 	brw = (brw < 80) ? brw : brw - 1;
104 
105 	read_buff[brw] = 0;
106 
107 	if (strcmp(test_str + 2, read_buff)) {
108 		TC_PRINT("Error - Data read does not match data written\n");
109 		TC_PRINT("Data read:\"%s\"\n\n", read_buff);
110 		return TC_FAIL;
111 	}
112 
113 	return TC_PASS;
114 }
115 
test_file_close(void)116 static int test_file_close(void)
117 {
118 	int res;
119 
120 	res = close(file);
121 	zassert_true(res == 0, "Failed closing file: %d, errno=%d\n", res, errno);
122 
123 	return res;
124 }
125 
test_file_delete(void)126 static int test_file_delete(void)
127 {
128 	int res;
129 
130 	res = unlink(TEST_FILE);
131 	if (res) {
132 		TC_PRINT("Error deleting file [%d]\n", res);
133 		return res;
134 	}
135 
136 	return res;
137 }
138 
139 /**
140  * @brief Test for POSIX open API
141  *
142  * @details Test opens new file through POSIX open API.
143  */
test_fs_open(void)144 void test_fs_open(void)
145 {
146 	zassert_true(test_file_open() == TC_PASS, NULL);
147 }
148 
149 /**
150  * @brief Test for POSIX write API
151  *
152  * @details Test writes some data through POSIX write API.
153  */
test_fs_write(void)154 void test_fs_write(void)
155 {
156 	zassert_true(test_file_write() == TC_PASS, NULL);
157 }
158 
159 /**
160  * @brief Test for POSIX write API
161  *
162  * @details Test reads data back through POSIX read API.
163  */
test_fs_read(void)164 void test_fs_read(void)
165 {
166 	zassert_true(test_file_read() == TC_PASS, NULL);
167 }
168 
169 /**
170  * @brief Test for POSIX close API
171  *
172  * @details Test closes the open file through POSIX close API.
173  */
test_fs_close(void)174 void test_fs_close(void)
175 {
176 	zassert_true(test_file_close() == TC_PASS, NULL);
177 }
178 
179 /**
180  * @brief Test for POSIX unlink API
181  *
182  * @details Test deletes a file through POSIX unlink API.
183  */
test_fs_unlink(void)184 void test_fs_unlink(void)
185 {
186 	zassert_true(test_file_delete() == TC_PASS, NULL);
187 }
188 
test_fs_fd_leak(void)189 void test_fs_fd_leak(void)
190 {
191 	const int reps =
192 	    MAX(CONFIG_POSIX_MAX_OPEN_FILES, CONFIG_POSIX_MAX_FDS) + 5;
193 
194 	for (int i = 0; i < reps; i++) {
195 		test_fs_open();
196 		test_fs_close();
197 	}
198 }
199