evdev: print a human time for ratelimit tests
authorPeter Hutterer <peter.hutterer@who-t.net>
Sun, 22 Mar 2020 00:31:44 +0000 (10:31 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Sun, 22 Mar 2020 00:35:21 +0000 (10:35 +1000)
No point in printing an interval of e.g. 2h as milliseconds, let's convert
this to something human-readable.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
src/evdev.h
src/util-time.h
test/test-utils.c

index 0eda22f999a20f063747e6fde0f1e1a215399a45..9a76ad80cec0865a35af5bd6351794ec4ea63b46 100644 (file)
@@ -814,12 +814,17 @@ evdev_log_msg_ratelimit(struct evdev_device *device,
        log_msg_va(evdev_libinput_context(device), priority, buf, args);
        va_end(args);
 
-       if (state == RATELIMIT_THRESHOLD)
+       if (state == RATELIMIT_THRESHOLD) {
+               struct human_time ht = to_human_time(ratelimit->interval);
                evdev_log_msg(device,
                              priority,
-                             "WARNING: log rate limit exceeded (%d msgs per %dms). Discarding future messages.\n",
+                             "WARNING: log rate limit exceeded (%d msgs per %d%s). "
+                             "Discarding future messages.\n",
                              ratelimit->burst,
-                             us2ms(ratelimit->interval));
+                             ht.value,
+                             ht.unit);
+
+       }
 }
 
 #define evdev_log_debug(d_, ...) evdev_log_msg((d_), LIBINPUT_LOG_PRIORITY_DEBUG, __VA_ARGS__)
index e8d3e41d9669de8e79bcb3694724fa23b7b77753..c28283bdfdae511a74a64a53f6d8d48bd08233e2 100644 (file)
 
 #include "config.h"
 
+#include <assert.h>
 #include <time.h>
 #include <stdint.h>
 #include <unistd.h>
 #include <linux/input.h>
 
+#include "util-macros.h"
+
 static inline void
 msleep(unsigned int ms)
 {
@@ -82,3 +85,42 @@ us2tv(uint64_t time)
 
        return tv;
 }
+
+struct human_time {
+       unsigned int value;
+       const char *unit;
+};
+
+/**
+ * Converts a time delta in µs to a human-readable time like "2h" or "4d"
+ */
+static inline struct human_time
+to_human_time(uint64_t us)
+{
+       struct human_time t;
+       struct c {
+               const char *unit;
+               unsigned int change_from_previous;
+               uint64_t limit;
+       } conversion[] = {
+               {"us", 1, 5000},
+               {"ms", 1000, 5000},
+               {"s", 1000, 120},
+               {"min", 60, 120},
+               {"h", 60, 48},
+               {"d", 24, ~0},
+       };
+       struct c *c;
+       uint64_t value = us;
+
+       ARRAY_FOR_EACH(conversion, c) {
+               value = value/c->change_from_previous;
+               if (value < c->limit) {
+                       t.unit = c->unit;
+                       t.value = value;
+                       return t;
+               }
+       }
+
+       assert(!"We should never get here");
+}
index 3304483e30a480bd2344e59d550097274a8ce207..007a9411c4a1cb7bfa53fcf4eb4b23f1dc45a5f5 100644 (file)
@@ -633,6 +633,37 @@ START_TEST(time_conversion)
 }
 END_TEST
 
+START_TEST(human_time)
+{
+       struct ht_tests {
+               uint64_t interval;
+               unsigned int value;
+               const char *unit;
+       } tests[] = {
+               { 0, 0, "us" },
+               { 123, 123, "us" },
+               { ms2us(5), 5, "ms" },
+               { ms2us(100), 100, "ms" },
+               { s2us(5), 5, "s" },
+               { s2us(100), 100, "s" },
+               { s2us(120), 2, "min" },
+               { 5 * s2us(60), 5, "min" },
+               { 120 * s2us(60), 2, "h" },
+               { 5 * 60 * s2us(60), 5, "h" },
+               { 48 * 60 * s2us(60), 2, "d" },
+               { 1000 * 24 * 60 * s2us(60), 1000, "d" },
+               { 0, 0, NULL },
+       };
+       for (int i = 0; tests[i].unit != NULL; i++) {
+               struct human_time ht;
+
+               ht = to_human_time(tests[i].interval);
+               ck_assert_int_eq(ht.value, tests[i].value);
+               ck_assert_str_eq(ht.unit, tests[i].unit);
+       }
+}
+END_TEST
+
 struct atoi_test {
        char *str;
        bool success;
@@ -1178,6 +1209,7 @@ litest_utils_suite(void)
        tcase_add_test(tc, strjoin_test);
        tcase_add_test(tc, strstrip_test);
        tcase_add_test(tc, time_conversion);
+       tcase_add_test(tc, human_time);
 
        tcase_add_test(tc, list_test_insert);
        tcase_add_test(tc, list_test_append);