This source file includes following definitions.
- empty_input_string
- bad_input_string
- trailing_chars
- typical_case
- double_overflow
- double_underflow
- main
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <stdarg.h>
13 #include <stddef.h>
14 #include <stdint.h>
15 #include <setjmp.h>
16 #include <cmocka.h>
17
18 #include <float.h>
19 #include <math.h>
20
21
22 #define LOCAL_BUF_SIZE 2 * DBL_MAX_10_EXP
23
24
25
26
27
28 #if HAVE_DECL_ASSERT_FLOAT_EQUAL == 0
29 #define assert_float_equal(a, b, epsilon) assert_true(fabs((a) - (b)) < (epsilon))
30 #endif
31
32 static void
33 empty_input_string(void **state)
34 {
35 double result;
36
37
38 assert_int_equal(pcmk__scan_double(NULL, &result, NULL, NULL), EINVAL);
39 assert_float_equal(result, PCMK__PARSE_DBL_DEFAULT, DBL_EPSILON);
40
41 assert_int_equal(pcmk__scan_double("", &result, NULL, NULL), EINVAL);
42 assert_float_equal(result, PCMK__PARSE_DBL_DEFAULT, DBL_EPSILON);
43
44
45 assert_int_equal(pcmk__scan_double(NULL, &result, "2.0", NULL), pcmk_rc_ok);
46 assert_float_equal(result, 2.0, DBL_EPSILON);
47
48 assert_int_equal(pcmk__scan_double("", &result, "2.0", NULL), EINVAL);
49 assert_float_equal(result, PCMK__PARSE_DBL_DEFAULT, DBL_EPSILON);
50 }
51
52 static void
53 bad_input_string(void **state)
54 {
55 double result;
56
57
58 assert_int_equal(pcmk__scan_double("asdf", &result, NULL, NULL), EINVAL);
59 assert_float_equal(result, PCMK__PARSE_DBL_DEFAULT, DBL_EPSILON);
60
61 assert_int_equal(pcmk__scan_double("as2.0", &result, NULL, NULL), EINVAL);
62 assert_float_equal(result, PCMK__PARSE_DBL_DEFAULT, DBL_EPSILON);
63
64
65 assert_int_equal(pcmk__scan_double("asdf", &result, "2.0", NULL), EINVAL);
66 assert_float_equal(result, PCMK__PARSE_DBL_DEFAULT, DBL_EPSILON);
67
68 assert_int_equal(pcmk__scan_double("as2.0", &result, "2.0", NULL), EINVAL);
69 assert_float_equal(result, PCMK__PARSE_DBL_DEFAULT, DBL_EPSILON);
70 }
71
72 static void
73 trailing_chars(void **state)
74 {
75 double result;
76 char *end_text;
77
78 assert_int_equal(pcmk__scan_double("2.0asdf", &result, NULL, &end_text), pcmk_rc_ok);
79 assert_float_equal(result, 2.0, DBL_EPSILON);
80 assert_string_equal(end_text, "asdf");
81 }
82
83 static void
84 typical_case(void **state)
85 {
86 char str[LOCAL_BUF_SIZE];
87 double result;
88
89 assert_int_equal(pcmk__scan_double("0.0", &result, NULL, NULL), pcmk_rc_ok);
90 assert_float_equal(result, 0.0, DBL_EPSILON);
91
92 assert_int_equal(pcmk__scan_double("1.0", &result, NULL, NULL), pcmk_rc_ok);
93 assert_float_equal(result, 1.0, DBL_EPSILON);
94
95 assert_int_equal(pcmk__scan_double("-1.0", &result, NULL, NULL), pcmk_rc_ok);
96 assert_float_equal(result, -1.0, DBL_EPSILON);
97
98 snprintf(str, LOCAL_BUF_SIZE, "%f", DBL_MAX);
99 assert_int_equal(pcmk__scan_double(str, &result, NULL, NULL), pcmk_rc_ok);
100 assert_float_equal(result, DBL_MAX, DBL_EPSILON);
101
102 snprintf(str, LOCAL_BUF_SIZE, "%f", -DBL_MAX);
103 assert_int_equal(pcmk__scan_double(str, &result, NULL, NULL), pcmk_rc_ok);
104 assert_float_equal(result, -DBL_MAX, DBL_EPSILON);
105 }
106
107 static void
108 double_overflow(void **state)
109 {
110 char str[LOCAL_BUF_SIZE];
111 double result;
112
113
114
115
116
117 snprintf(str, LOCAL_BUF_SIZE, "1e%d", DBL_MAX_10_EXP + 1);
118 assert_int_equal(pcmk__scan_double(str, &result, NULL, NULL), EOVERFLOW);
119 assert_true(result > DBL_MAX);
120
121 snprintf(str, LOCAL_BUF_SIZE, "-1e%d", DBL_MAX_10_EXP + 1);
122 assert_int_equal(pcmk__scan_double(str, &result, NULL, NULL), EOVERFLOW);
123 assert_true(result < -DBL_MAX);
124 }
125
126 static void
127 double_underflow(void **state)
128 {
129 char str[LOCAL_BUF_SIZE];
130 double result;
131
132
133
134
135
136
137
138 snprintf(str, LOCAL_BUF_SIZE, "1e%d", DBL_MIN_10_EXP - 1);
139 assert_int_equal(pcmk__scan_double(str, &result, NULL, NULL), pcmk_rc_underflow);
140 assert_true(result >= 0.0);
141 assert_true(result <= DBL_MIN);
142
143 snprintf(str, LOCAL_BUF_SIZE, "-1e%d", DBL_MIN_10_EXP - 1);
144 assert_int_equal(pcmk__scan_double(str, &result, NULL, NULL), pcmk_rc_underflow);
145 assert_true(result <= 0.0);
146 assert_true(result >= -DBL_MIN);
147 }
148
149 int main(int argc, char **argv)
150 {
151 const struct CMUnitTest tests[] = {
152
153 cmocka_unit_test(empty_input_string),
154 cmocka_unit_test(bad_input_string),
155 cmocka_unit_test(trailing_chars),
156
157
158 cmocka_unit_test(typical_case),
159 cmocka_unit_test(double_overflow),
160 cmocka_unit_test(double_underflow),
161 };
162
163 cmocka_set_message_output(CM_OUTPUT_TAP);
164 return cmocka_run_group_tests(tests, NULL, NULL);
165 }
166