summaryrefslogtreecommitdiffstats
path: root/src/test
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-02-17 16:53:11 +0100
committerLennart Poettering <lennart@poettering.net>2021-02-18 22:36:34 +0100
commit3b6e71ad0351c5ed2dd8382a63ab3581fa2d6174 (patch)
treeb231e01ef6f3b58582cd0ff374f22b129a8a5235 /src/test
parentpercent-util: when parsing permyriads, permit percents too with 1 place after... (diff)
downloadsystemd-3b6e71ad0351c5ed2dd8382a63ab3581fa2d6174.tar.xz
systemd-3b6e71ad0351c5ed2dd8382a63ab3581fa2d6174.zip
util: add some helpers for converting percent/permille/permyriad to parts of 2^32-1
At various places we accept values scaled to the range 0…2^32-1 which are exposed to the user as percentages/permille/permyriad. Let's add some helper macros (actually: typesafe macro-like functions) that help with converting our internal encoding to the external encodings. benefits: some of the previous code rounded up, some down. let's always round to nearest, to ensure that our conversions are reversible. Also, check for overflows correctly. This also adds a test that makes sure that for the full percent/permille/permyriad ranges we can convert forth and back without loss of accuracy.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/test-percent-util.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/test/test-percent-util.c b/src/test/test-percent-util.c
index 75f8a6c83d..b8801438a7 100644
--- a/src/test/test-percent-util.c
+++ b/src/test/test-percent-util.c
@@ -2,6 +2,7 @@
#include "percent-util.h"
#include "tests.h"
+#include "time-util.h"
static void test_parse_percent(void) {
assert_se(parse_percent("") == -EINVAL);
@@ -150,6 +151,51 @@ static void test_parse_permyriad_unbounded(void) {
assert_se(parse_permyriad_unbounded("42949672.96%") == -ERANGE);
}
+static void test_scale(void) {
+ /* Check some fixed values */
+ assert_se(UINT32_SCALE_FROM_PERCENT(0) == 0);
+ assert_se(UINT32_SCALE_FROM_PERCENT(50) == UINT32_MAX/2+1);
+ assert_se(UINT32_SCALE_FROM_PERCENT(100) == UINT32_MAX);
+
+ assert_se(UINT32_SCALE_FROM_PERMILLE(0) == 0);
+ assert_se(UINT32_SCALE_FROM_PERMILLE(500) == UINT32_MAX/2+1);
+ assert_se(UINT32_SCALE_FROM_PERMILLE(1000) == UINT32_MAX);
+
+ assert_se(UINT32_SCALE_FROM_PERMYRIAD(0) == 0);
+ assert_se(UINT32_SCALE_FROM_PERMYRIAD(5000) == UINT32_MAX/2+1);
+ assert_se(UINT32_SCALE_FROM_PERMYRIAD(10000) == UINT32_MAX);
+
+ /* Make sure there's no numeric noise on the 0%…100% scale when converting from percent and back. */
+ for (int percent = 0; percent <= 100; percent++) {
+ log_debug("%i%% → %" PRIu32 " → %i%%",
+ percent,
+ UINT32_SCALE_FROM_PERCENT(percent),
+ UINT32_SCALE_TO_PERCENT(UINT32_SCALE_FROM_PERCENT(percent)));
+
+ assert_se(UINT32_SCALE_TO_PERCENT(UINT32_SCALE_FROM_PERCENT(percent)) == percent);
+ }
+
+ /* Make sure there's no numeric noise on the 0‰…1000‰ scale when converting from permille and back. */
+ for (int permille = 0; permille <= 1000; permille++) {
+ log_debug("%i‰ → %" PRIu32 " → %i‰",
+ permille,
+ UINT32_SCALE_FROM_PERMILLE(permille),
+ UINT32_SCALE_TO_PERMILLE(UINT32_SCALE_FROM_PERMILLE(permille)));
+
+ assert_se(UINT32_SCALE_TO_PERMILLE(UINT32_SCALE_FROM_PERMILLE(permille)) == permille);
+ }
+
+ /* Make sure there's no numeric noise on the 0‱…10000‱ scale when converting from permyriad and back. */
+ for (int permyriad = 0; permyriad <= 10000; permyriad++) {
+ log_debug("%i‱ → %" PRIu32 " → %i‱",
+ permyriad,
+ UINT32_SCALE_FROM_PERMYRIAD(permyriad),
+ UINT32_SCALE_TO_PERMYRIAD(UINT32_SCALE_FROM_PERMYRIAD(permyriad)));
+
+ assert_se(UINT32_SCALE_TO_PERMYRIAD(UINT32_SCALE_FROM_PERMYRIAD(permyriad)) == permyriad);
+ }
+}
+
int main(int argc, char *argv[]) {
test_setup_logging(LOG_DEBUG);
@@ -159,6 +205,7 @@ int main(int argc, char *argv[]) {
test_parse_permille_unbounded();
test_parse_permyriad();
test_parse_permyriad_unbounded();
+ test_scale();
return 0;
}