]> git.ipfire.org Git - thirdparty/lldpd.git/blame - tests/check_fixedpoint.c
tests: display tests/test-suite.log on errors
[thirdparty/lldpd.git] / tests / check_fixedpoint.c
CommitLineData
f730f6c5
VB
1/* -*- mode: c; c-file-style: "openbsd" -*- */
2/*
3 * Copyright (c) 2012 Vincent Bernat <bernat@luffy.cx>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <check.h>
19#include <stdlib.h>
20
21#include "../src/lib/fixedpoint.h"
22
23#ifdef ENABLE_LLDPMED
24
25START_TEST(test_string_parsing_suffix) {
26 char *end;
27 fp_strtofp("4541T", &end, 14, 8);
28 ck_assert_int_eq(*end, 'T');
29 fp_strtofp("4541.U", &end, 14, 8);
30 ck_assert_int_eq(*end, 'U');
31 fp_strtofp("4541.676V", &end, 14, 8);
32 ck_assert_int_eq(*end, 'V');
33}
34END_TEST
35
36START_TEST(test_string_parsing_positive_int) {
37 struct fp_number fp = fp_strtofp("4541T", NULL, 14, 8);
38 ck_assert_int_eq(fp.integer.bits, 14);
39 ck_assert_int_eq(fp.integer.value, 4541);
40 ck_assert_int_eq(fp.fraction.bits, 8);
41 ck_assert_int_eq(fp.fraction.value, 0);
42 ck_assert_int_eq(fp.fraction.precision, 0);
43}
44END_TEST
45
46START_TEST(test_string_parsing_negative_int) {
47 struct fp_number fp = fp_strtofp("-4214N", NULL, 14, 8);
48 ck_assert_int_eq(fp.integer.bits, 14);
49 ck_assert_int_eq(fp.integer.value, -4214);
50 ck_assert_int_eq(fp.fraction.bits, 8);
51 ck_assert_int_eq(fp.fraction.value, 0);
52 ck_assert_int_eq(fp.fraction.precision, 0);
53}
54END_TEST
55
56START_TEST(test_string_parsing_positive_int_overflow) {
57 struct fp_number fp1 = fp_strtofp("4098", NULL, 13, 8);
58 struct fp_number fp2 = fp_strtofp("4096", NULL, 13, 8);
59 struct fp_number fp3 = fp_strtofp("4095", NULL, 13, 8);
60 struct fp_number fp4 = fp_strtofp("4094", NULL, 13, 8);
61 ck_assert_int_eq(fp1.integer.value, 4095);
62 ck_assert_int_eq(fp2.integer.value, 4095);
63 ck_assert_int_eq(fp3.integer.value, 4095);
64 ck_assert_int_eq(fp4.integer.value, 4094);
65}
66END_TEST
67
68START_TEST(test_string_parsing_negative_int_overflow) {
69 struct fp_number fp1 = fp_strtofp("-4097", NULL, 13, 8);
70 struct fp_number fp2 = fp_strtofp("-4096", NULL, 13, 8);
71 struct fp_number fp3 = fp_strtofp("-4095", NULL, 13, 8);
72 struct fp_number fp4 = fp_strtofp("-4094", NULL, 13, 8);
73 ck_assert_int_eq(fp1.integer.value, -4096);
74 ck_assert_int_eq(fp2.integer.value, -4096);
75 ck_assert_int_eq(fp3.integer.value, -4095);
76 ck_assert_int_eq(fp4.integer.value, -4094);
77}
78END_TEST
79
80START_TEST(test_string_parsing_positive_float) {
81 struct fp_number fp1 = fp_strtofp("1542.6250E", NULL, 13, 20);
82 ck_assert_int_eq(fp1.integer.value, 1542);
83 ck_assert_int_eq(fp1.fraction.precision, 14);
84 ck_assert_int_eq((fp1.fraction.value * 10000) >> fp1.fraction.bits, 6250);
85
86 struct fp_number fp2 = fp_strtofp("1542.06250E", NULL, 13, 4);
87 ck_assert_int_eq(fp2.integer.value, 1542);
88 ck_assert_int_eq(fp2.fraction.precision, 4);
89 ck_assert_int_eq((fp2.fraction.value * 10000) >> fp2.fraction.bits, 625);
90}
91END_TEST
92
93START_TEST(test_string_parsing_negative_float) {
94 struct fp_number fp = fp_strtofp("-11542.6250N", NULL, 15, 4);
95 ck_assert_int_eq(fp.integer.value, -11542);
96 ck_assert_int_eq(fp.fraction.precision, 4);
97 ck_assert_int_eq((fp.fraction.value * 10000) >> fp.fraction.bits, 6250);
98}
99END_TEST
100
101START_TEST(test_string_parsing_no_fract_part) {
102 struct fp_number fp = fp_strtofp("11542.", NULL, 15, 4);
103 ck_assert_int_eq(fp.integer.value, 11542);
104 ck_assert_int_eq(fp.fraction.value, 0);
105 ck_assert_int_eq(fp.fraction.precision, 1);
106}
107END_TEST
108
109START_TEST(test_string_parsing_no_int_part) {
110 struct fp_number fp = fp_strtofp(".6250E", NULL, 13, 4);
111 ck_assert_int_eq(fp.integer.value, 0);
112 ck_assert_int_eq(fp.fraction.precision, 4);
113 ck_assert_int_eq((fp.fraction.value * 10000) >> fp.fraction.bits, 6250);
114}
115END_TEST
116
117
118START_TEST(test_string_representation_positive_int) {
119 struct fp_number fp1 = fp_strtofp("214", NULL, 9, 9);
120 struct fp_number fp2 = fp_strtofp("11178.0000", NULL, 15, 9);
121 ck_assert_str_eq(fp_fptostr(fp1, NULL), "214");
122 ck_assert_str_eq(fp_fptostr(fp2, NULL), "11178");
123 ck_assert_str_eq(fp_fptostr(fp2, "ES"), "11178E");
124}
125END_TEST
126
127START_TEST(test_string_representation_negative_int) {
128 struct fp_number fp1 = fp_strtofp("-214", NULL, 9, 9);
129 struct fp_number fp2 = fp_strtofp("-11178.0000", NULL, 15, 9);
130 ck_assert_str_eq(fp_fptostr(fp1, NULL), "-214");
131 ck_assert_str_eq(fp_fptostr(fp2, NULL), "-11178");
132 ck_assert_str_eq(fp_fptostr(fp2, "ES"), "11178S");
133}
134END_TEST
135
136START_TEST(test_string_representation_positive_float) {
137 struct fp_number fp = fp_strtofp("214.6250", NULL, 9, 20);
138 ck_assert_str_eq(fp_fptostr(fp, NULL), "214.6250");
139 ck_assert_str_eq(fp_fptostr(fp, "ES"), "214.6250E");
140}
141END_TEST
142
143START_TEST(test_string_representation_positive_float_with_leading_zero) {
144 struct fp_number fp = fp_strtofp("214.06250", NULL, 9, 24);
145 ck_assert_str_eq(fp_fptostr(fp, NULL), "214.06250");
146 ck_assert_str_eq(fp_fptostr(fp, "ES"), "214.06250E");
147}
148END_TEST
149
150START_TEST(test_string_representation_negative_float) {
151 struct fp_number fp1 = fp_strtofp("-214.625", NULL, 22, 10);
152 struct fp_number fp2 = fp_strtofp("-415.5", NULL, 22, 4);
153 ck_assert_str_eq(fp_fptostr(fp1, NULL), "-214.625");
154 ck_assert_str_eq(fp_fptostr(fp2, NULL), "-415.5");
155 ck_assert_str_eq(fp_fptostr(fp2, "ES"), "415.5S");
156}
157END_TEST
158
159START_TEST(test_buffer_representation_positive_float) {
160 unsigned char buffer[5] = {};
161 unsigned char expected[] = { 0x21 << 2, 47 << 1, 0x68, 0x00, 0x00 };
162 /* 47.2031250 = 47 + 2**-3 + 2**-4 + 2**-6, precision = 9+24 */
163 struct fp_number fp = fp_strtofp("47.2031250", NULL, 9, 25);
164 fp_fptobuf(fp, buffer, 0);
165 fail_unless(memcmp(buffer, expected, sizeof(expected)) == 0);
166}
167END_TEST
168
169START_TEST(test_buffer_representation_negative_float) {
170 unsigned char buffer[5] = {};
171 unsigned char expected[] = { (0x21 << 2) | 3, 0xa1, 0x98, 0x00, 0x00 };
172 /* 47.2031250 = 000101111.0011010000000000000000000 */
173 /* -47.2031250 = 111010000.1100101111111111111111111 + 1 */
174 /* -47.2031250 = 111010000.1100110000000000000000000 */
175 struct fp_number fp = fp_strtofp("-47.2031250", NULL, 9, 25);
176 fp_fptobuf(fp, buffer, 0);
177 fail_unless(memcmp(buffer, expected, sizeof(expected)) == 0);
178}
179END_TEST
180
181START_TEST(test_buffer_representation_with_shift) {
182 unsigned char buffer[] = { 0x77, 0xc6, 0x0, 0x0, 0x0, 0x0, 0xc7 };
183 unsigned char expected[] = { 0x77, 0xc8, 0x45, 0xe6, 0x80, 0x00, 0x07 };
184 struct fp_number fp = fp_strtofp("47.2031250", NULL, 9, 25);
185 fp_fptobuf(fp, buffer, 12);
186 fail_unless(memcmp(buffer, expected, sizeof(buffer)) == 0);
187}
188END_TEST
189
190START_TEST(test_buffer_representation_altitude) {
191 unsigned char buffer[5] = {};
192 unsigned char expected[] = { (22 + 4) << 2, 0, 0, 14 << 4 | 1 << 3, 0 };
193 struct fp_number fp = fp_strtofp("14.5", NULL, 22, 8);
194 fp_fptobuf(fp, buffer, 0);
195 fail_unless(memcmp(buffer, expected, sizeof(buffer)) == 0);
196}
197END_TEST
198
199START_TEST(test_buffer_parsing_positive_float) {
200 unsigned char buffer[] = { 0x21 << 2, 47 << 1, 0x68, 0x00, 0x00 };
201 struct fp_number fp = fp_buftofp(buffer, 9, 25, 0);
202 ck_assert_int_eq(fp.integer.value, 47);
203 ck_assert_int_eq(fp.integer.bits, 9);
204 ck_assert_int_eq((fp.fraction.value * 10000000) >> fp.fraction.bits, 2031250);
205 ck_assert_int_eq(fp.fraction.bits, 25);
206 ck_assert_int_eq(fp.fraction.precision, 24);
207}
208END_TEST
209
210START_TEST(test_buffer_parsing_negative_float) {
211 unsigned char buffer[] = { (0x21 << 2) | 3, 0xa1, 0x98, 0x00, 0x00 };
212 struct fp_number fp = fp_buftofp(buffer, 9, 25, 0);
213 ck_assert_int_eq(fp.integer.value, -47);
214 ck_assert_int_eq(fp.integer.bits, 9);
215 ck_assert_int_eq((fp.fraction.value * 10000000) >> fp.fraction.bits, 2031250);
216 ck_assert_int_eq(fp.fraction.bits, 25);
217 ck_assert_int_eq(fp.fraction.precision, 24);
218}
219END_TEST
220
221/* This is some corner case */
222START_TEST(test_buffer_parsing_positive_float_2) {
223 unsigned char buffer[] = { 0x40, 0x9c, 0x80, 0x00, 0x00 };
224 struct fp_number fp = fp_buftofp(buffer, 9, 25, 0);
225 ck_assert_int_eq(fp.integer.value, 78);
226}
227END_TEST
228
229START_TEST(test_buffer_parsing_positive_float_with_shift) {
230 unsigned char buffer[] = { 0x77, 0xc8, 0x45, 0xe6, 0x80, 0x00, 0x07 };
231 struct fp_number fp = fp_buftofp(buffer, 9, 25, 12);
232 ck_assert_int_eq(fp.integer.value, 47);
233 ck_assert_int_eq(fp.integer.bits, 9);
234 ck_assert_int_eq((fp.fraction.value * 10000000) >> fp.fraction.bits, 2031250);
235 ck_assert_int_eq(fp.fraction.bits, 25);
236 ck_assert_int_eq(fp.fraction.precision, 24);
237}
238END_TEST
239
240START_TEST(test_buffer_parsing_negative_float_with_shift) {
241 unsigned char buffer[] = { 0x00, 0xff, (0x21 << 2) | 3, 0xa1, 0x98, 0x00, 0x00 };
242 struct fp_number fp = fp_buftofp(buffer, 9, 25, 16);
243 ck_assert_int_eq(fp.integer.value, -47);
244 ck_assert_int_eq(fp.integer.bits, 9);
245 ck_assert_int_eq((fp.fraction.value * 10000000) >> fp.fraction.bits, 2031250);
246 ck_assert_int_eq(fp.fraction.bits, 25);
247 ck_assert_int_eq(fp.fraction.precision, 24);
248}
249END_TEST
250
251START_TEST(test_negate_positive) {
252 struct fp_number fp = fp_strtofp("14.5", NULL, 9, 25);
253 struct fp_number nfp = fp_negate(fp);
254 ck_assert_int_eq(nfp.integer.value, -14);
255 ck_assert_int_eq(fp.fraction.value, nfp.fraction.value);
256 ck_assert_str_eq(fp_fptostr(nfp, NULL), "-14.5");
257}
258END_TEST
259
260START_TEST(test_negate_negative) {
261 struct fp_number fp = fp_strtofp("-14.5", NULL, 9, 25);
262 struct fp_number nfp = fp_negate(fp);
263 ck_assert_int_eq(nfp.integer.value, 14);
264 ck_assert_int_eq(fp.fraction.value, nfp.fraction.value);
265 ck_assert_str_eq(fp_fptostr(nfp, NULL), "14.5");
266}
267END_TEST
268
269#endif
270
271Suite *
272fixedpoint_suite(void)
273{
274 Suite *s = suite_create("Fixed point representation");
275
276#ifdef ENABLE_LLDPMED
277 TCase *tc_fp = tcase_create("Fixed point representation");
278 tcase_add_test(tc_fp, test_string_parsing_suffix);
279 tcase_add_test(tc_fp, test_string_parsing_positive_int);
280 tcase_add_test(tc_fp, test_string_parsing_negative_int);
281 tcase_add_test(tc_fp, test_string_parsing_no_fract_part);
282 tcase_add_test(tc_fp, test_string_parsing_no_int_part);
283 tcase_add_test(tc_fp, test_string_parsing_positive_int_overflow);
284 tcase_add_test(tc_fp, test_string_parsing_negative_int_overflow);
285 tcase_add_test(tc_fp, test_string_parsing_positive_float);
286 tcase_add_test(tc_fp, test_string_parsing_negative_float);
287 tcase_add_test(tc_fp, test_string_representation_positive_int);
288 tcase_add_test(tc_fp, test_string_representation_negative_int);
289 tcase_add_test(tc_fp, test_string_representation_positive_float);
290 tcase_add_test(tc_fp, test_string_representation_positive_float_with_leading_zero);
291 tcase_add_test(tc_fp, test_string_representation_negative_float);
292 tcase_add_test(tc_fp, test_buffer_representation_positive_float);
293 tcase_add_test(tc_fp, test_buffer_representation_negative_float);
294 tcase_add_test(tc_fp, test_buffer_representation_with_shift);
295 tcase_add_test(tc_fp, test_buffer_representation_altitude);
296 tcase_add_test(tc_fp, test_buffer_parsing_positive_float);
297 tcase_add_test(tc_fp, test_buffer_parsing_positive_float_2);
298 tcase_add_test(tc_fp, test_buffer_parsing_negative_float);
299 tcase_add_test(tc_fp, test_buffer_parsing_positive_float_with_shift);
300 tcase_add_test(tc_fp, test_buffer_parsing_negative_float_with_shift);
301 tcase_add_test(tc_fp, test_negate_positive);
302 tcase_add_test(tc_fp, test_negate_negative);
303 suite_add_tcase(s, tc_fp);
304#endif
305
306 return s;
307}
308
9997f8e4
VB
309/* Disable leak detection sanitizer */
310int __lsan_is_turned_off() {
311 return 1;
312}
313
f730f6c5
VB
314int
315main()
316{
317 int number_failed;
318 Suite *s = fixedpoint_suite();
319 SRunner *sr = srunner_create(s);
320 srunner_run_all(sr, CK_ENV);
321 number_failed = srunner_ntests_failed(sr);
322 srunner_free(sr);
323 return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
324}