diff options
author | Thomas Haller <thaller@redhat.com> | 2023-07-24 20:05:40 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-07-24 20:05:57 +0200 |
commit | 91b904db248d0fb710ea0700bb1aaf0eee0ecc88 (patch) | |
tree | d5e9fa3a11200371fd1f25cf6899ff8bf9575642 | |
parent | 6519a9173f900b364f014a2321a17aa6bf652e6d (diff) | |
parent | 96bbe55c8513f1c80d4c85fe829ef2aef35e1f51 (diff) | |
download | libnl-91b904db248d0fb710ea0700bb1aaf0eee0ecc88.tar.gz |
tests: merge branch 'gobenji:test-cache-mngr-improvements'
https://github.com/thom311/libnl/pull/335
-rw-r--r-- | tests/test-cache-mngr.c | 144 |
1 files changed, 131 insertions, 13 deletions
diff --git a/tests/test-cache-mngr.c b/tests/test-cache-mngr.c index 97614520..33cbd8d2 100644 --- a/tests/test-cache-mngr.c +++ b/tests/test-cache-mngr.c @@ -2,21 +2,42 @@ #include <netlink/cache.h> #include <netlink/cli/utils.h> #include <signal.h> +#include <stdbool.h> +#include <sys/time.h> +#include <time.h> #include <netlink-private/cache-api.h> #include <linux/netlink.h> static int quit = 0; +static int change = 1; +static int print_ts = 0; -static struct nl_dump_params dp = { +static struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, }; +static void print_timestamp(FILE *fp) +{ + struct timeval tv; + char tshort[40]; + struct tm *tm; + + gettimeofday(&tv, NULL); + tm = localtime(&tv.tv_sec); + + strftime(tshort, sizeof(tshort), "%Y-%m-%dT%H:%M:%S", tm); + fprintf(fp, "[%s.%06ld] ", tshort, tv.tv_usec); +} + static void change_cb(struct nl_cache *cache, struct nl_object *obj, int action, void *data) { + if (print_ts) + print_timestamp(stdout); + if (action == NL_ACT_NEW) printf("NEW "); else if (action == NL_ACT_DEL) @@ -24,7 +45,10 @@ static void change_cb(struct nl_cache *cache, struct nl_object *obj, else if (action == NL_ACT_CHANGE) printf("CHANGE "); - nl_object_dump(obj, &dp); + nl_object_dump(obj, ¶ms); + fflush(stdout); + + change = 1; } static void sigint(int arg) @@ -32,34 +56,128 @@ static void sigint(int arg) quit = 1; } +static void print_usage(FILE* stream, const char *name) +{ + fprintf(stream, + "Usage: %s [OPTIONS]... <cache name>... \n" + "\n" + "OPTIONS\n" + " -f, --format=TYPE Output format { brief | details | stats }\n" + " Default: brief\n" + " -d, --dump Dump cache content after a change.\n" + " -i, --interval=TIME Dump cache content after TIME seconds when there is no\n" + " change; 0 to disable. Default: 1\n" + " -I, --iter Iterate over all address families when updating caches.\n" + " -t, --tshort Print a short timestamp before change messages.\n" + " -h, --help Show this help text.\n" + , name); +} + int main(int argc, char *argv[]) { + bool dump_on_change = false, dump_on_timeout = true, iter = false; struct nl_cache_mngr *mngr; - struct nl_cache *cache; - int err, i; - - dp.dp_fd = stdout; - - signal(SIGINT, sigint); + int timeout = 1000, err; + + for (;;) { + static struct option long_opts[] = { + { "format", required_argument, 0, 'f' }, + { "dump", no_argument, 0, 'd' }, + { "interval", required_argument, 0, 'i' }, + { "iter", no_argument, 0, 'I' }, + { "tshort", no_argument, 0, 't' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } + }; + int c; + + c = getopt_long(argc, argv, "hf:di:It", long_opts, NULL); + if (c == -1) + break; + + switch (c) { + char *endptr; + long interval; + + case 'f': + params.dp_type = nl_cli_parse_dumptype(optarg); + break; + + case 'd': + dump_on_change = true; + break; + + case 'i': + errno = 0; + interval = strtol(optarg, &endptr, 0); + if (interval < 0 || errno || *endptr) { + nl_cli_fatal(EINVAL, "Invalid interval \"%s\".\n", + optarg); + exit(1); + } + if (!interval) { + dump_on_timeout = false; + } else { + timeout = interval * 1000; + } + + break; + + case 'I': + iter = true; + break; + + case 't': + print_ts = true; + break; + + case 'h': + print_usage(stdout, argv[0]); + exit(0); + + case '?': + print_usage(stderr, argv[0]); + exit(1); + } + } err = nl_cache_mngr_alloc(NULL, NETLINK_ROUTE, NL_AUTO_PROVIDE, &mngr); if (err < 0) nl_cli_fatal(err, "Unable to allocate cache manager: %s", nl_geterror(err)); - for (i = 1; i < argc; i++) { - err = nl_cache_mngr_add(mngr, argv[i], &change_cb, NULL, &cache); + while (optind < argc) { + struct nl_cache *cache; + + err = nl_cache_alloc_name(argv[optind], &cache); + if (err < 0) + nl_cli_fatal(err, "Couldn't add cache %s: %s\n", + argv[optind], nl_geterror(err)); + + if (iter) + nl_cache_set_flags(cache, NL_CACHE_AF_ITER); + + err = nl_cache_mngr_add_cache(mngr, cache, &change_cb, NULL); if (err < 0) nl_cli_fatal(err, "Unable to add cache %s: %s", - argv[i], nl_geterror(err)); + argv[optind], nl_geterror(err)); + + optind++; } + params.dp_fd = stdout; + signal(SIGINT, sigint); + while (!quit) { - int err = nl_cache_mngr_poll(mngr, 1000); + err = nl_cache_mngr_poll(mngr, timeout); if (err < 0 && err != -NLE_INTR) nl_cli_fatal(err, "Polling failed: %s", nl_geterror(err)); - nl_cache_mngr_info(mngr, &dp); + if (dump_on_timeout || (dump_on_change && change)) { + nl_cache_mngr_info(mngr, ¶ms); + fflush(stdout); + change = 0; + } } nl_cache_mngr_free(mngr); |