1/*-
2 *   BSD LICENSE
3 *
4 *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5 *   All rights reserved.
6 *
7 *   Redistribution and use in source and binary forms, with or without
8 *   modification, are permitted provided that the following conditions
9 *   are met:
10 *
11 *     * Redistributions of source code must retain the above copyright
12 *       notice, this list of conditions and the following disclaimer.
13 *     * Redistributions in binary form must reproduce the above copyright
14 *       notice, this list of conditions and the following disclaimer in
15 *       the documentation and/or other materials provided with the
16 *       distribution.
17 *     * Neither the name of Intel Corporation nor the names of its
18 *       contributors may be used to endorse or promote products derived
19 *       from this software without specific prior written permission.
20 *
21 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include "test.h"
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <errno.h>
39
40/* eal_filesystem.h is not a public header file, so use relative path */
41#include "../../lib/librte_eal/common/eal_filesystem.h"
42
43static int
44test_parse_sysfs_value(void)
45{
46	char filename[PATH_MAX] = "";
47	char proc_path[PATH_MAX];
48	char file_template[] = "/tmp/eal_test_XXXXXX";
49	int tmp_file_handle = -1;
50	FILE *fd = NULL;
51	unsigned valid_number;
52	unsigned long retval = 0;
53
54#ifdef RTE_EXEC_ENV_BSDAPP
55	/* BSD doesn't have /proc/pid/fd */
56	return 0;
57#endif
58
59	printf("Testing function eal_parse_sysfs_value()\n");
60
61	/* get a temporary filename to use for all tests - create temp file handle and then
62	 * use /proc to get the actual file that we can open */
63	tmp_file_handle = mkstemp(file_template);
64	if (tmp_file_handle == -1) {
65		perror("mkstemp() failure");
66		goto error;
67	}
68	snprintf(proc_path, sizeof(proc_path), "/proc/self/fd/%d", tmp_file_handle);
69	if (readlink(proc_path, filename, sizeof(filename)) < 0) {
70		perror("readlink() failure");
71		goto error;
72	}
73	printf("Temporary file is: %s\n", filename);
74
75	/* test we get an error value if we use file before it's created */
76	printf("Test reading a missing file ...\n");
77	if (eal_parse_sysfs_value("/dev/not-quite-null", &retval) == 0) {
78		printf("Error with eal_parse_sysfs_value() - returned success on reading empty file\n");
79		goto error;
80	}
81	printf("Confirmed return error when reading empty file\n");
82
83	/* test reading a valid number value with "\n" on the end */
84	printf("Test reading valid values ...\n");
85	valid_number = 15;
86	fd = fopen(filename,"w");
87	if (fd == NULL) {
88		printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
89		goto error;
90	}
91	fprintf(fd,"%u\n", valid_number);
92	fclose(fd);
93	fd = NULL;
94	if (eal_parse_sysfs_value(filename, &retval) < 0) {
95		printf("eal_parse_sysfs_value() returned error - test failed\n");
96		goto error;
97	}
98	if (retval != valid_number) {
99		printf("Invalid value read by eal_parse_sysfs_value() - test failed\n");
100		goto error;
101	}
102	printf("Read '%u\\n' ok\n", valid_number);
103
104	/* test reading a valid hex number value with "\n" on the end */
105	valid_number = 25;
106	fd = fopen(filename,"w");
107	if (fd == NULL) {
108		printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
109		goto error;
110	}
111	fprintf(fd,"0x%x\n", valid_number);
112	fclose(fd);
113	fd = NULL;
114	if (eal_parse_sysfs_value(filename, &retval) < 0) {
115		printf("eal_parse_sysfs_value() returned error - test failed\n");
116		goto error;
117	}
118	if (retval != valid_number) {
119		printf("Invalid value read by eal_parse_sysfs_value() - test failed\n");
120		goto error;
121	}
122	printf("Read '0x%x\\n' ok\n", valid_number);
123
124	printf("Test reading invalid values ...\n");
125
126	/* test reading an empty file - expect failure!*/
127	fd = fopen(filename,"w");
128	if (fd == NULL) {
129		printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
130		goto error;
131	}
132	fclose(fd);
133	fd = NULL;
134	if (eal_parse_sysfs_value(filename, &retval) == 0) {
135		printf("eal_parse_sysfs_value() read invalid value  - test failed\n");
136		goto error;
137	}
138
139	/* test reading a valid number value *without* "\n" on the end - expect failure!*/
140	valid_number = 3;
141	fd = fopen(filename,"w");
142	if (fd == NULL) {
143		printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
144		goto error;
145	}
146	fprintf(fd,"%u", valid_number);
147	fclose(fd);
148	fd = NULL;
149	if (eal_parse_sysfs_value(filename, &retval) == 0) {
150		printf("eal_parse_sysfs_value() read invalid value  - test failed\n");
151		goto error;
152	}
153
154	/* test reading a valid number value followed by string - expect failure!*/
155	valid_number = 3;
156	fd = fopen(filename,"w");
157	if (fd == NULL) {
158		printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
159		goto error;
160	}
161	fprintf(fd,"%uJ\n", valid_number);
162	fclose(fd);
163	fd = NULL;
164	if (eal_parse_sysfs_value(filename, &retval) == 0) {
165		printf("eal_parse_sysfs_value() read invalid value  - test failed\n");
166		goto error;
167	}
168
169	/* test reading a non-numeric value - expect failure!*/
170	fd = fopen(filename,"w");
171	if (fd == NULL) {
172		printf("line %d, Error opening %s: %s\n", __LINE__, filename, strerror(errno));
173		goto error;
174	}
175	fprintf(fd,"error\n");
176	fclose(fd);
177	fd = NULL;
178	if (eal_parse_sysfs_value(filename, &retval) == 0) {
179		printf("eal_parse_sysfs_value() read invalid value  - test failed\n");
180		goto error;
181	}
182
183	close(tmp_file_handle);
184	unlink(filename);
185	printf("eal_parse_sysfs_value() - OK\n");
186	return 0;
187
188error:
189	if (fd)
190		fclose(fd);
191	if (tmp_file_handle > 0)
192		close(tmp_file_handle);
193	if (filename[0] != '\0')
194		unlink(filename);
195	return -1;
196}
197
198static int
199test_eal_fs(void)
200{
201	if (test_parse_sysfs_value() < 0)
202		return -1;
203	return 0;
204}
205
206REGISTER_TEST_COMMAND(eal_fs_autotest, test_eal_fs);
207