1/*
2 * Copyright (C) 2012 Marios Makris <marios.makris@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like.  Any license provided herein, whether implied or
15 * otherwise, applies only to this software file.  Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24/*
25 * Test program for the bytes_by_prefix program in /lib
26 *
27 * This program tests a few predefined values against the expected predefined
28 * results, upon sucesfull completion, it prints the message:
29 * "Tests sucesfully completed!" else it prints that there were an error
30 * and the value as well as the type on which it failed (int, long, long long)
31 * at the time of the error in order for someone to be able to trace
32 * it back as well as the total number of errors encountered along with the
33 * message: "Some test(s): (number of tests) failed please review!"
34 */
35
36#include <stdio.h>
37#include <stdlib.h>
38
39#include "bytes_by_prefix.h"
40
41struct test_vals {
42	char *val;
43	long long res;
44};
45
46/*
47 * Array with generic values suitable for all operations.
48 */
49struct test_vals test[] = {
50	{"1", 1},
51	{"5", 5},
52	{"10", 10},
53	{"552558", 552558},
54	{"0", 0},
55	{"1b", 512},
56	{"5b", 2560},
57	{"0b", 0},
58	{"1k", 1024},
59	{"5k", 5120},
60	{"552558k", 565819392},
61	{"0k", 0},
62	{"1m", 1048576},
63	{"5m", 5242880},
64	{"0m", 0},
65	{"1g", 1073741824},
66	{"0g", 0},
67	/*
68	 * Negative Test Values
69	 */
70	{"a", -1},
71	{"k", -1},
72	{"m", -1},
73	{"g", -1},
74	{"K", -1},
75	{"M", -1},
76	{"G", -1},
77	{"5km", -1},
78	{"1a", -1},
79	{"1mabc", -1},
80	{"a1", -1},
81	{"k1", -1},
82	{"1 k", -1},
83	{"1k g", -1},
84	{"-5", -1},
85	{"-5b", -1},
86	{"-2k", -1},
87	{"-2m", -1},
88	{"-2g", -1},
89	{"-2K", -1},
90	{"-2M", -1},
91	{"-2G", -1}
92};
93
94/*
95 * Specific values for int operations
96 */
97struct test_vals test_i[] = {
98/*
99 * In case of 64b system as the results of capital multipliers are multiplied
100 * by the sizeof(long) or sizeof(long long) respectively.
101 * Check "/lib/bytes_by_prefix.c" file for more information.
102 */
103#if __SIZEOF_LONG__ == 8
104	{"5K", 40960},
105	{"0K", 0},
106	{"5M", 41943040}
107/*
108 * In case of 32b system as the results of capital multipliers are multiplied
109 * by the sizeof(long) or sizeof(long long) respectively.
110 * Check "/lib/bytes_by_prefix.c" file for more information.
111 */
112#else
113	{"5K", 20480},
114	{"0K", 0},
115	{"5M", 20971520}
116#endif
117};
118
119/*
120 * Specific values for long operations
121 */
122struct test_vals test_l[] = {
123/*
124 * In case of 64b system as the results of capital multipliers are multiplied
125 * by the sizeof(long) or sizeof(long long) respectively.
126 * Check "/lib/bytes_by_prefix.c" file for more information.
127 */
128#if __SIZEOF_LONG__ == 8
129	{"552558m", 579399057408},
130	{"5g", 5368709120},
131	{"5K", 40960},
132	{"5M", 41943040},
133	{"1G", 8589934592}
134/*
135 * In case of 32b system as the results of capital multipliers are multiplied
136 * by the sizeof(long) or sizeof(long long) respectively.
137 * Check "/lib/bytes_by_prefix.c" file for more information.
138 */
139#else
140	{"552558m", -1},
141	{"5g", -1},
142	{"5K", 20480},
143	{"5M", 20971520},
144	{"1G", -1}
145#endif
146};
147
148/*
149 * Specific values for long long operations
150 */
151struct test_vals test_ll[] = {
152	{"552558m", 579399057408LL},
153	{"5g", 5368709120LL},
154	{"5K", 40960},
155	{"552558K", 4526555136LL},
156	{"5M", 41943040},
157	{"552558M", 4635192459264LL},
158	{"5G", 42949672960LL},
159	{"552558G", 4746437078286336LL}
160};
161
162static int test_values(void)
163{
164	/*
165	 * 1st position of the array denotes the valid int operations
166	 * 2nd position of the array denotes the valid long operations
167	 * 3rd position of the array denotes the valid long long operations
168	 */
169	int valid_count[3];
170	int tests_number[3];	/* int / long / long long */
171	int i;
172	int error_count = 0;
173	int elements;		/* Number of elements inside the test array. */
174
175	elements = sizeof(test) / sizeof(struct test_vals);
176	/*
177	 * Initializing counters.
178	 */
179	for (i = 0; i < 3; i++) {
180		valid_count[i] = 0;
181		tests_number[i] = elements;
182	}
183
184	/*
185	 * The "generic" test loop. If the result of the function equals the
186	 * expected predifined result, then increase the valid counter
187	 */
188	for (i = 0; i < elements; i++) {
189		if (bytes_by_prefix(test[i].val) == test[i].res) {
190			valid_count[0]++;
191		} else {
192			printf("Test value:%s failed on int.\n", test[i].val);
193			error_count++;
194		}
195
196		if (lbytes_by_prefix(test[i].val) == test[i].res) {
197			valid_count[1]++;
198		} else {
199			printf("Test value:%s failed on long.\n", test[i].val);
200			error_count++;
201		}
202
203		if (llbytes_by_prefix(test[i].val) == test[i].res) {
204			valid_count[2]++;
205		} else {
206			printf("Test value:%s failed on long long.\n",
207			       test[i].val);
208			error_count++;
209		}
210	}
211
212	elements = sizeof(test_i) / sizeof(struct test_vals);
213	tests_number[0] += elements;
214
215	/*
216	 * Int specific test loop
217	 */
218	for (i = 0; i < elements; i++) {
219		if (bytes_by_prefix(test_i[i].val) == test_i[i].res) {
220			valid_count[0]++;
221		} else {
222			printf("Test value:%s failed on int.\n", test_i[i].val);
223			error_count++;
224		}
225	}
226
227	elements = sizeof(test_l) / sizeof(struct test_vals);
228	tests_number[1] += elements;
229
230	/*
231	 * Long specific test loop
232	 */
233	for (i = 0; i < elements; i++) {
234		if (lbytes_by_prefix(test_l[i].val) == test_l[i].res) {
235			valid_count[1]++;
236		} else {
237			printf("Test value:%s failed on long.\n",
238			       test_l[i].val);
239			error_count++;
240		}
241	}
242
243	elements = sizeof(test_ll) / sizeof(struct test_vals);
244	tests_number[2] += elements;
245
246	/*
247	 * Long long specific test loop
248	 */
249	for (i = 0; i < elements; i++) {
250		if (llbytes_by_prefix(test_ll[i].val) == test_ll[i].res) {
251			valid_count[2]++;
252		} else {
253			printf("Test value:%s failed on long long.\n",
254			       test_ll[i].val);
255			error_count++;
256		}
257	}
258
259	fprintf(stdout, "Succesfull int tests:%d/%d\n", valid_count[0],
260		tests_number[0]);
261	fprintf(stdout, "Succesfull long tests:%d/%d\n", valid_count[1],
262		tests_number[1]);
263	fprintf(stdout, "Succesfull long long tests:%d/%d\n", valid_count[2],
264		tests_number[2]);
265
266	return error_count;
267}
268
269int main(void)
270{
271	int errors = test_values();
272
273	if (errors > 0) {
274		fprintf(stderr, "\nSome test(s):(%d) failed please review!\n",
275			errors);
276		exit(1);
277	} else {
278		fprintf(stdout, "Tests succesfully completed!\n");
279	}
280
281	return 0;
282}
283