]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/strtol.cc
update sources to 12.2.8
[ceph.git] / ceph / src / test / strtol.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2011 Dreamhost
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #include "common/strtol.h"
16 #include <math.h>
17 #include <string>
18 #include <map>
19
20 #include "gtest/gtest.h"
21
22 static void test_strict_strtoll(const char *str, long long expected, int base)
23 {
24 std::string err;
25 long long val = strict_strtoll(str, base, &err);
26 if (!err.empty()) {
27 ASSERT_EQ(err, "");
28 }
29 else {
30 ASSERT_EQ(val, expected);
31 }
32 }
33
34 static void test_strict_strtol(const char *str, long expected)
35 {
36 std::string err;
37 long val = strict_strtol(str, 10, &err);
38 if (!err.empty()) {
39 ASSERT_EQ(err, "");
40 }
41 else {
42 ASSERT_EQ(val, expected);
43 }
44 }
45
46 static void test_strict_strtod(const char *str, double expected)
47 {
48 std::string err;
49 double val = strict_strtod(str, &err);
50 if (!err.empty()) {
51 ASSERT_EQ(err, "");
52 }
53 else {
54 // when comparing floats, use a margin of error
55 if ((expected - 0.001 > val) || (expected + 0.001 < val)) {
56 ASSERT_EQ(val, expected);
57 }
58 }
59 }
60
61 static void test_strict_strtof(const char *str, float expected)
62 {
63 std::string err;
64 float val = strict_strtof(str, &err);
65 if (!err.empty()) {
66 ASSERT_EQ(err, "");
67 }
68 else {
69 // when comparing floats, use a margin of error
70 if ((expected - 0.001 > val) || (expected + 0.001 < val)) {
71 ASSERT_EQ(val, expected);
72 }
73 }
74 }
75
76 TEST(StrToL, Simple1) {
77 test_strict_strtoll("123", 123, 10);
78 test_strict_strtoll("0", 0, 10);
79 test_strict_strtoll("-123", -123, 10);
80 test_strict_strtoll("8796093022208", 8796093022208LL, 10);
81 test_strict_strtoll("-8796093022208", -8796093022208LL, 10);
82 test_strict_strtoll("123", 123, 0);
83 test_strict_strtoll("0x7b", 123, 0);
84 test_strict_strtoll("4d2", 1234, 16);
85
86 test_strict_strtol("208", 208);
87 test_strict_strtol("-4", -4);
88 test_strict_strtol("0", 0);
89 test_strict_strtol("2147483646", 2147483646);
90
91 test_strict_strtof("0.05", 0.05);
92 test_strict_strtof("0", 0.0);
93 test_strict_strtof("-0", 0.0);
94 test_strict_strtof("10000000.5", 10000000.5);
95
96 test_strict_strtod("-0.2", -0.2);
97 test_strict_strtod("0.1", 0.1);
98 test_strict_strtod("0", 0.0);
99 }
100
101 static void test_strict_strtoll_err(const char *str)
102 {
103 std::string err;
104 strict_strtoll(str, 10, &err);
105 ASSERT_NE(err, "");
106 }
107
108 static void test_strict_strtol_err(const char *str)
109 {
110 std::string err;
111 strict_strtol(str, 10, &err);
112 ASSERT_NE(err, "");
113 }
114
115 static void test_strict_strtod_err(const char *str)
116 {
117 std::string err;
118 strict_strtod(str, &err);
119 ASSERT_NE(err, "");
120 }
121
122 static void test_strict_strtof_err(const char *str)
123 {
124 std::string err;
125 strict_strtof(str, &err);
126 ASSERT_NE(err, "");
127 }
128
129 TEST(StrToL, Error1) {
130 test_strict_strtoll_err("604462909807314587353088"); // overflow
131 test_strict_strtoll_err("aw shucks"); // invalid
132 test_strict_strtoll_err("343245 aw shucks"); // invalid chars at end
133 test_strict_strtoll_err("-"); // invalid
134
135 test_strict_strtol_err("35 aw shucks"); // invalid chars at end
136 test_strict_strtol_err("--0");
137 test_strict_strtol_err("-");
138
139 test_strict_strtod_err("345345.0-");
140 test_strict_strtod_err("34.0 garbo");
141
142 test_strict_strtof_err("0.05.0");
143 }
144
145
146 static void test_strict_iecstrtoll(const char *str)
147 {
148 std::string err;
149 strict_iecstrtoll(str, &err);
150 ASSERT_EQ(err, "");
151 }
152
153 static void test_strict_iecstrtoll_units(const std::string& foo,
154 std::string u, const int m)
155 {
156 std::string s(foo);
157 s.append(u);
158 const char *str = s.c_str();
159 std::string err;
160 uint64_t r = strict_iecstrtoll(str, &err);
161 ASSERT_EQ(err, "");
162
163 str = foo.c_str();
164 std::string err2;
165 long long tmp = strict_strtoll(str, 10, &err2);
166 ASSERT_EQ(err2, "");
167 tmp = (tmp << m);
168 ASSERT_EQ(tmp, (long long)r);
169 }
170
171 TEST(IECStrToLL, WithUnits) {
172 std::map<std::string,int> units;
173 units["B"] = 0;
174 units["K"] = 10;
175 units["M"] = 20;
176 units["G"] = 30;
177 units["T"] = 40;
178 units["P"] = 50;
179 units["E"] = 60;
180 units["Ki"] = 10;
181 units["Mi"] = 20;
182 units["Gi"] = 30;
183 units["Ti"] = 40;
184 units["Pi"] = 50;
185 units["Ei"] = 60;
186
187 for (std::map<std::string,int>::iterator p = units.begin();
188 p != units.end(); ++p) {
189 // the upper bound of uint64_t is 2^64 = 4E
190 test_strict_iecstrtoll_units("4", p->first, p->second);
191 test_strict_iecstrtoll_units("1", p->first, p->second);
192 test_strict_iecstrtoll_units("0", p->first, p->second);
193 }
194 }
195
196 TEST(IECStrToLL, WithoutUnits) {
197 test_strict_iecstrtoll("1024");
198 test_strict_iecstrtoll("1152921504606846976");
199 test_strict_iecstrtoll("0");
200 }
201
202 static void test_strict_iecstrtoll_err(const char *str)
203 {
204 std::string err;
205 strict_iecstrtoll(str, &err);
206 ASSERT_NE(err, "");
207 }
208
209 TEST(IECStrToLL, Error) {
210 test_strict_iecstrtoll_err("1024F");
211 test_strict_iecstrtoll_err("QDDSA");
212 test_strict_iecstrtoll_err("1b");
213 test_strict_iecstrtoll_err("100k");
214 test_strict_iecstrtoll_err("1000m");
215 test_strict_iecstrtoll_err("1g");
216 test_strict_iecstrtoll_err("20t");
217 test_strict_iecstrtoll_err("100p");
218 test_strict_iecstrtoll_err("1000e");
219 test_strict_iecstrtoll_err("B");
220 test_strict_iecstrtoll_err("M");
221 test_strict_iecstrtoll_err("BM");
222 test_strict_iecstrtoll_err("B0wef");
223 test_strict_iecstrtoll_err("0m");
224 test_strict_iecstrtoll_err("-1"); // it returns uint64_t
225 test_strict_iecstrtoll_err("-1K");
226 test_strict_iecstrtoll_err("1Bi");
227 test_strict_iecstrtoll_err("Bi");
228 test_strict_iecstrtoll_err("bi");
229 test_strict_iecstrtoll_err("gi");
230 test_strict_iecstrtoll_err("100ki");
231 test_strict_iecstrtoll_err("1000mi");
232 test_strict_iecstrtoll_err("1gi");
233 test_strict_iecstrtoll_err("20ti");
234 test_strict_iecstrtoll_err("100pi");
235 test_strict_iecstrtoll_err("1000ei");
236 // the upper bound of uint64_t is 2^64 = 4E, so 1024E overflows
237 test_strict_iecstrtoll_err("1024E"); // overflows after adding the suffix
238 }
239
240 // since strict_iecstrtoll is an alias of strict_iec_cast<uint64_t>(), quite a few
241 // of cases are covered by existing test cases of strict_iecstrtoll already.
242 TEST(StrictIECCast, Error) {
243 {
244 std::string err;
245 // the SI prefix is way too large for `int`.
246 (void)strict_iec_cast<int>("2E", &err);
247 ASSERT_NE(err, "");
248 }
249 {
250 std::string err;
251 (void)strict_iec_cast<int>("-2E", &err);
252 ASSERT_NE(err, "");
253 }
254 {
255 std::string err;
256 (void)strict_iec_cast<int>("1T", &err);
257 ASSERT_NE(err, "");
258 }
259 {
260 std::string err;
261 (void)strict_iec_cast<int64_t>("2E", &err);
262 ASSERT_EQ(err, "");
263 }
264 {
265 std::string err;
266 (void)strict_iec_cast<int64_t>("-2E", &err);
267 ASSERT_EQ(err, "");
268 }
269 {
270 std::string err;
271 (void)strict_iec_cast<int64_t>("1T", &err);
272 ASSERT_EQ(err, "");
273 }
274 }
275
276
277 static void test_strict_sistrtoll(const char *str)
278 {
279 std::string err;
280 strict_sistrtoll(str, &err);
281 ASSERT_EQ(err, "");
282 }
283
284 static void test_strict_sistrtoll_units(const std::string& foo,
285 std::string u, const long long m)
286 {
287 std::string s(foo);
288 s.append(u);
289 const char *str = s.c_str();
290 std::string err;
291 uint64_t r = strict_sistrtoll(str, &err);
292 ASSERT_EQ(err, "");
293
294 str = foo.c_str();
295 std::string err2;
296 long long tmp = strict_strtoll(str, 10, &err2);
297 ASSERT_EQ(err2, "");
298 tmp = (tmp * m);
299 ASSERT_EQ(tmp, (long long)r);
300 }
301
302 TEST(SIStrToLL, WithUnits) {
303 std::map<std::string,long long> units;
304 units["K"] = pow(10, 3);
305 units["M"] = pow(10, 6);
306 units["G"] = pow(10, 9);
307 units["T"] = pow(10, 12);
308 units["P"] = pow(10, 15);
309 units["E"] = pow(10, 18);
310
311 for (std::map<std::string,long long>::iterator p = units.begin();
312 p != units.end(); ++p) {
313 // the upper bound of uint64_t is 2^64 = 4E
314 test_strict_sistrtoll_units("4", p->first, p->second);
315 test_strict_sistrtoll_units("1", p->first, p->second);
316 test_strict_sistrtoll_units("0", p->first, p->second);
317 }
318 }
319
320 TEST(SIStrToLL, WithoutUnits) {
321 test_strict_sistrtoll("1024");
322 test_strict_sistrtoll("1152921504606846976");
323 test_strict_sistrtoll("0");
324 }
325
326 static void test_strict_sistrtoll_err(const char *str)
327 {
328 std::string err;
329 strict_sistrtoll(str, &err);
330 ASSERT_NE(err, "");
331 }
332
333 TEST(SIStrToLL, Error) {
334 test_strict_sistrtoll_err("1024F");
335 test_strict_sistrtoll_err("QDDSA");
336 test_strict_sistrtoll_err("1b");
337 test_strict_sistrtoll_err("100k");
338 test_strict_sistrtoll_err("1000m");
339 test_strict_sistrtoll_err("1g");
340 test_strict_sistrtoll_err("20t");
341 test_strict_sistrtoll_err("100p");
342 test_strict_sistrtoll_err("1000e");
343 test_strict_sistrtoll_err("B");
344 test_strict_sistrtoll_err("M");
345 test_strict_sistrtoll_err("BM");
346 test_strict_sistrtoll_err("B0wef");
347 test_strict_sistrtoll_err("0m");
348 test_strict_sistrtoll_err("-1"); // it returns uint64_t
349 test_strict_sistrtoll_err("-1K");
350 test_strict_sistrtoll_err("1Bi");
351 test_strict_sistrtoll_err("Bi");
352 test_strict_sistrtoll_err("bi");
353 test_strict_sistrtoll_err("gi");
354 test_strict_sistrtoll_err("100ki");
355 test_strict_sistrtoll_err("1000mi");
356 test_strict_sistrtoll_err("1gi");
357 test_strict_sistrtoll_err("20ti");
358 test_strict_sistrtoll_err("100pi");
359 test_strict_sistrtoll_err("1000ei");
360 test_strict_sistrtoll_err("1B");
361 // the upper bound of uint64_t is 2^64 = 4E, so 1024E overflows
362 test_strict_sistrtoll_err("1024E"); // overflows after adding the suffix
363 }
364
365 // since strict_sistrtoll is an alias of strict_si_cast<uint64_t>(), quite a few
366 // of cases are covered by existing test cases of strict_sistrtoll already.
367 TEST(StrictSICast, Error) {
368 {
369 std::string err;
370 // the SI prefix is way too large for `int`.
371 (void)strict_si_cast<int>("2E", &err);
372 ASSERT_NE(err, "");
373 }
374 {
375 std::string err;
376 (void)strict_si_cast<int>("-2E", &err);
377 ASSERT_NE(err, "");
378 }
379 {
380 std::string err;
381 (void)strict_si_cast<int>("1T", &err);
382 ASSERT_NE(err, "");
383 }
384 {
385 std::string err;
386 (void)strict_si_cast<int64_t>("2E", &err);
387 ASSERT_EQ(err, "");
388 }
389 {
390 std::string err;
391 (void)strict_si_cast<int64_t>("-2E", &err);
392 ASSERT_EQ(err, "");
393 }
394 {
395 std::string err;
396 (void)strict_si_cast<int64_t>("1T", &err);
397 ASSERT_EQ(err, "");
398 }
399 }
400
401 /*
402 * Local Variables:
403 * compile-command: "cd .. ; make unittest_strtol && ./unittest_strtol"
404 * End:
405 */