Blame SOURCES/0075-tcurl-test-refactor-so-new-options-can-be-added-more.patch

bb7cd1
From a886247bcdb1c551486c34a8d4eccd046a11382f Mon Sep 17 00:00:00 2001
bb7cd1
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
bb7cd1
Date: Fri, 24 Feb 2017 12:23:01 +0100
bb7cd1
Subject: [PATCH 75/90] tcurl test: refactor so new options can be added more
bb7cd1
 easily
bb7cd1
bb7cd1
Just to make the tool a little bit nicer and more flexible.
bb7cd1
bb7cd1
Reviewed-by: Simo Sorce <simo@redhat.com>
bb7cd1
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
bb7cd1
(cherry picked from commit b800a6d09244359959404aca81c6796a58cafbcb)
bb7cd1
---
bb7cd1
 src/tests/tcurl_test_tool.c | 334 +++++++++++++++++++++++++++-----------------
bb7cd1
 1 file changed, 209 insertions(+), 125 deletions(-)
bb7cd1
bb7cd1
diff --git a/src/tests/tcurl_test_tool.c b/src/tests/tcurl_test_tool.c
bb7cd1
index 9a6266f89131ffd3a561e857af85df9854c44949..e5fc9705db415650d849b89c3d18e41574b7e28b 100644
bb7cd1
--- a/src/tests/tcurl_test_tool.c
bb7cd1
+++ b/src/tests/tcurl_test_tool.c
bb7cd1
@@ -28,26 +28,39 @@
bb7cd1
 
bb7cd1
 struct tool_ctx {
bb7cd1
     bool verbose;
bb7cd1
-
bb7cd1
-    errno_t error;
bb7cd1
     bool done;
bb7cd1
 
bb7cd1
     size_t nreqs;
bb7cd1
 };
bb7cd1
 
bb7cd1
+struct tool_options {
bb7cd1
+    int debug;
bb7cd1
+    int verbose;
bb7cd1
+
bb7cd1
+    enum tcurl_http_method method;
bb7cd1
+    const char *socket_path;
bb7cd1
+};
bb7cd1
+
bb7cd1
 static void request_done(struct tevent_req *req)
bb7cd1
 {
bb7cd1
-    int http_code;
bb7cd1
+    struct tool_ctx *tool_ctx;
bb7cd1
     struct sss_iobuf *outbuf;
bb7cd1
-    struct tool_ctx *tool_ctx = tevent_req_callback_data(req,
bb7cd1
-                                                         struct tool_ctx);
bb7cd1
+    int http_code;
bb7cd1
+    errno_t ret;
bb7cd1
 
bb7cd1
-    tool_ctx->error = tcurl_request_recv(tool_ctx, req, &outbuf, &http_code);
bb7cd1
+    tool_ctx = tevent_req_callback_data(req, struct tool_ctx);
bb7cd1
+
bb7cd1
+    ret = tcurl_request_recv(tool_ctx, req, &outbuf, &http_code);
bb7cd1
     talloc_zfree(req);
bb7cd1
 
bb7cd1
-    if (tool_ctx->error != EOK) {
bb7cd1
-        DEBUG(SSSDBG_FATAL_FAILURE, "HTTP request failed: %d\n", tool_ctx->error);
bb7cd1
+    tool_ctx->nreqs--;
bb7cd1
+    if (tool_ctx->nreqs == 0) {
bb7cd1
         tool_ctx->done = true;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE, "HTTP request failed [%d]: %s\n",
bb7cd1
+              ret, sss_strerror(ret));
bb7cd1
         return;
bb7cd1
     } else if (tool_ctx->verbose) {
bb7cd1
         printf("Request HTTP code: %d\n", http_code);
bb7cd1
@@ -55,167 +68,171 @@ static void request_done(struct tevent_req *req)
bb7cd1
                (const char *) sss_iobuf_get_data(outbuf));
bb7cd1
         talloc_zfree(outbuf);
bb7cd1
     }
bb7cd1
-
bb7cd1
-    tool_ctx->nreqs--;
bb7cd1
-    if (tool_ctx->nreqs == 0) {
bb7cd1
-        tool_ctx->done = true;
bb7cd1
-    }
bb7cd1
 }
bb7cd1
 
bb7cd1
-int main(int argc, const char *argv[])
bb7cd1
+static errno_t
bb7cd1
+parse_options(poptContext pc, struct tool_options *opts)
bb7cd1
 {
bb7cd1
     int opt;
bb7cd1
-    poptContext pc;
bb7cd1
-
bb7cd1
-    int pc_debug = 0;
bb7cd1
-    int pc_verbose = 0;
bb7cd1
-    const char *socket_path = NULL;
bb7cd1
-    const char *extra_arg_ptr;
bb7cd1
-
bb7cd1
-    static const char *headers[] = {
bb7cd1
-        "Content-type: application/octet-stream",
bb7cd1
-        NULL,
bb7cd1
-    };
bb7cd1
-
bb7cd1
-    struct poptOption long_options[] = {
bb7cd1
-        POPT_AUTOHELP
bb7cd1
-        { "debug", '\0', POPT_ARG_INT, &pc_debug, 0,
bb7cd1
-          "The debug level to run with", NULL },
bb7cd1
-        { "socket-path", 's', POPT_ARG_STRING, &socket_path, 0,
bb7cd1
-          "The path to the HTTP server socket", NULL },
bb7cd1
-        { "get", 'g', POPT_ARG_NONE, NULL, 'g', "Perform a HTTP GET (default)", NULL },
bb7cd1
-        { "put", 'p', POPT_ARG_NONE, NULL, 'p', "Perform a HTTP PUT", NULL },
bb7cd1
-        { "post", 'o', POPT_ARG_NONE, NULL, 'o', "Perform a HTTP POST", NULL },
bb7cd1
-        { "del", 'd', POPT_ARG_NONE, NULL, 'd', "Perform a HTTP DELETE", NULL },
bb7cd1
-        { "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "Print response code and body", NULL },
bb7cd1
-        POPT_TABLEEND
bb7cd1
-    };
bb7cd1
-
bb7cd1
-    struct tevent_req *req;
bb7cd1
-    struct tevent_context *ev;
bb7cd1
-    enum tcurl_http_method method = TCURL_HTTP_GET;
bb7cd1
-    struct tcurl_ctx *ctx;
bb7cd1
-    struct tcurl_request *tcurl_req;
bb7cd1
-    struct tool_ctx *tool_ctx;
bb7cd1
-
bb7cd1
-    const char *urls[MAXREQ] = { 0 };
bb7cd1
-    struct sss_iobuf **inbufs;
bb7cd1
-
bb7cd1
-    size_t n_reqs = 0;
bb7cd1
-
bb7cd1
-    debug_prg_name = argv[0];
bb7cd1
-    pc = poptGetContext(NULL, argc, argv, long_options, 0);
bb7cd1
-    poptSetOtherOptionHelp(pc, "HTTPDATA");
bb7cd1
 
bb7cd1
     while ((opt = poptGetNextOpt(pc)) > 0) {
bb7cd1
         switch (opt) {
bb7cd1
         case 'g':
bb7cd1
-            method = TCURL_HTTP_GET;
bb7cd1
+            opts->method = TCURL_HTTP_GET;
bb7cd1
             break;
bb7cd1
         case 'p':
bb7cd1
-            method = TCURL_HTTP_PUT;
bb7cd1
+            opts->method = TCURL_HTTP_PUT;
bb7cd1
             break;
bb7cd1
         case 'o':
bb7cd1
-            method = TCURL_HTTP_POST;
bb7cd1
+            opts->method = TCURL_HTTP_POST;
bb7cd1
             break;
bb7cd1
         case 'd':
bb7cd1
-            method = TCURL_HTTP_DELETE;
bb7cd1
-            break;
bb7cd1
-        case 'v':
bb7cd1
-            pc_verbose = 1;
bb7cd1
+            opts->method = TCURL_HTTP_DELETE;
bb7cd1
             break;
bb7cd1
         default:
bb7cd1
             DEBUG(SSSDBG_FATAL_FAILURE, "Unexpected option\n");
bb7cd1
-            return 1;
bb7cd1
+            return EINVAL;
bb7cd1
         }
bb7cd1
     }
bb7cd1
 
bb7cd1
-    DEBUG_CLI_INIT(pc_debug);
bb7cd1
-
bb7cd1
-    tool_ctx = talloc_zero(NULL, struct tool_ctx);
bb7cd1
-    if (tool_ctx == NULL) {
bb7cd1
-        DEBUG(SSSDBG_CRIT_FAILURE, "Could not init tool context\n");
bb7cd1
-        return 1;
bb7cd1
+    if (opt != -1) {
bb7cd1
+        poptPrintUsage(pc, stderr, 0);
bb7cd1
+        fprintf(stderr, "%s", poptStrerror(opt));
bb7cd1
+        return EINVAL;
bb7cd1
     }
bb7cd1
 
bb7cd1
-    inbufs = talloc_zero_array(tool_ctx, struct sss_iobuf *, MAXREQ);
bb7cd1
-    if (inbufs == NULL) {
bb7cd1
-        talloc_zfree(tool_ctx);
bb7cd1
-        return 1;
bb7cd1
+    return EOK;
bb7cd1
+}
bb7cd1
+
bb7cd1
+static errno_t
bb7cd1
+prepare_requests(TALLOC_CTX *mem_ctx,
bb7cd1
+                 poptContext pc,
bb7cd1
+                 struct tool_options *opts,
bb7cd1
+                 struct tcurl_request ***_requests,
bb7cd1
+                 size_t *_num_requests)
bb7cd1
+{
bb7cd1
+    struct tcurl_request **requests;
bb7cd1
+    const char *arg;
bb7cd1
+    const char *url;
bb7cd1
+    struct sss_iobuf *body;
bb7cd1
+    errno_t ret;
bb7cd1
+    size_t i;
bb7cd1
+
bb7cd1
+    static const char *headers[] = {
bb7cd1
+        "Content-type: application/octet-stream",
bb7cd1
+        NULL,
bb7cd1
+    };
bb7cd1
+
bb7cd1
+    requests = talloc_zero_array(mem_ctx, struct tcurl_request *, MAXREQ + 1);
bb7cd1
+    if (requests == NULL) {
bb7cd1
+        return ENOMEM;
bb7cd1
     }
bb7cd1
 
bb7cd1
-    while ((extra_arg_ptr = poptGetArg(pc)) != NULL) {
bb7cd1
-        switch(method) {
bb7cd1
+    i = 0;
bb7cd1
+    while ((arg = poptGetArg(pc)) != NULL) {
bb7cd1
+        if (i >= MAXREQ) {
bb7cd1
+            fprintf(stderr, _("Too many requests!\n"));
bb7cd1
+            ret = EINVAL;
bb7cd1
+            goto done;
bb7cd1
+        }
bb7cd1
+
bb7cd1
+        switch (opts->method) {
bb7cd1
         case TCURL_HTTP_GET:
bb7cd1
         case TCURL_HTTP_DELETE:
bb7cd1
-        case TCURL_HTTP_POST:
bb7cd1
-            urls[n_reqs++] = extra_arg_ptr;
bb7cd1
+            url = arg;
bb7cd1
+            body = NULL;
bb7cd1
             break;
bb7cd1
         case TCURL_HTTP_PUT:
bb7cd1
-            if (urls[n_reqs] == NULL) {
bb7cd1
-                urls[n_reqs] = extra_arg_ptr;
bb7cd1
-            } else {
bb7cd1
-                inbufs[n_reqs] = sss_iobuf_init_readonly(
bb7cd1
-                                              inbufs,
bb7cd1
-                                              (uint8_t *) discard_const(extra_arg_ptr),
bb7cd1
-                                              strlen(extra_arg_ptr));
bb7cd1
-                if (inbufs[n_reqs] == NULL) {
bb7cd1
-                    DEBUG(SSSDBG_CRIT_FAILURE, "Could not init input buffer\n");
bb7cd1
-                    talloc_zfree(tool_ctx);
bb7cd1
-                    return 1;
bb7cd1
-                }
bb7cd1
-                n_reqs++;
bb7cd1
+        case TCURL_HTTP_POST:
bb7cd1
+            url = arg;
bb7cd1
+
bb7cd1
+            arg = poptGetArg(pc);
bb7cd1
+            if (arg == NULL) {
bb7cd1
+                body = NULL;
bb7cd1
+                break;
bb7cd1
+            }
bb7cd1
+
bb7cd1
+            body = sss_iobuf_init_readonly(requests,
bb7cd1
+                                           discard_const_p(uint8_t, arg),
bb7cd1
+                                           strlen(arg));
bb7cd1
+            if (body == NULL) {
bb7cd1
+                ret = ENOMEM;
bb7cd1
+                goto done;
bb7cd1
             }
bb7cd1
             break;
bb7cd1
+        default:
bb7cd1
+            DEBUG(SSSDBG_CRIT_FAILURE, "Invalid method!\n");
bb7cd1
+            ret = EINVAL;
bb7cd1
+            goto done;
bb7cd1
         }
bb7cd1
+
bb7cd1
+        requests[i] = tcurl_http(requests, opts->method, opts->socket_path,
bb7cd1
+                                 url, headers, body);
bb7cd1
+        if (requests[i] == NULL) {
bb7cd1
+            ret = ENOMEM;
bb7cd1
+            goto done;
bb7cd1
+        }
bb7cd1
+
bb7cd1
+        i++;
bb7cd1
     }
bb7cd1
 
bb7cd1
-    if (opt != -1) {
bb7cd1
-        poptPrintUsage(pc, stderr, 0);
bb7cd1
-        fprintf(stderr, "%s", poptStrerror(opt));
bb7cd1
-        talloc_zfree(tool_ctx);
bb7cd1
-        return 1;
bb7cd1
+    *_requests = requests;
bb7cd1
+    *_num_requests = i;
bb7cd1
+
bb7cd1
+    ret = EOK;
bb7cd1
+
bb7cd1
+done:
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        talloc_free(requests);
bb7cd1
     }
bb7cd1
 
bb7cd1
-    if (!socket_path) {
bb7cd1
-        DEBUG(SSSDBG_FATAL_FAILURE, "Please specify the socket path\n");
bb7cd1
-        poptPrintUsage(pc, stderr, 0);
bb7cd1
-        talloc_zfree(tool_ctx);
bb7cd1
-        return 1;
bb7cd1
+    return ret;
bb7cd1
+}
bb7cd1
+
bb7cd1
+static errno_t
bb7cd1
+run_requests(struct tool_ctx *tool_ctx,
bb7cd1
+             struct tcurl_request **requests)
bb7cd1
+{
bb7cd1
+    TALLOC_CTX *tmp_ctx;
bb7cd1
+    struct tcurl_ctx *tcurl_ctx;
bb7cd1
+    struct tevent_context *ev;
bb7cd1
+    struct tevent_req *req;
bb7cd1
+    errno_t ret;
bb7cd1
+    int i;
bb7cd1
+
bb7cd1
+    tmp_ctx = talloc_new(NULL);
bb7cd1
+    if (tmp_ctx == NULL) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n");
bb7cd1
+        return ENOMEM;
bb7cd1
     }
bb7cd1
 
bb7cd1
-    tool_ctx->nreqs = n_reqs;
bb7cd1
-    tool_ctx->verbose = !!pc_verbose;
bb7cd1
+    if (requests == NULL || requests[0] == NULL) {
bb7cd1
+        ret = EOK;
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
 
bb7cd1
-    ev = tevent_context_init(tool_ctx);
bb7cd1
+    ev = tevent_context_init(tmp_ctx);
bb7cd1
     if (ev == NULL) {
bb7cd1
         DEBUG(SSSDBG_CRIT_FAILURE, "Could not init tevent context\n");
bb7cd1
-        talloc_zfree(tool_ctx);
bb7cd1
-        return 1;
bb7cd1
+        ret = ENOMEM;
bb7cd1
+        goto done;
bb7cd1
     }
bb7cd1
 
bb7cd1
-    ctx = tcurl_init(tool_ctx, ev);
bb7cd1
-    if (ctx == NULL) {
bb7cd1
+    tcurl_ctx = tcurl_init(tmp_ctx, ev);
bb7cd1
+    if (tcurl_ctx == NULL) {
bb7cd1
         DEBUG(SSSDBG_FATAL_FAILURE, "Could not init tcurl context\n");
bb7cd1
-        talloc_zfree(tool_ctx);
bb7cd1
-        return 1;
bb7cd1
+        ret = ENOMEM;
bb7cd1
+        goto done;
bb7cd1
     }
bb7cd1
 
bb7cd1
-    for (size_t i = 0; i < n_reqs; i++) {
bb7cd1
-        tcurl_req = tcurl_http(tool_ctx, method, socket_path,
bb7cd1
-                               urls[i], headers, inbufs[i]);
bb7cd1
-        if (tcurl_req == NULL) {
bb7cd1
-            DEBUG(SSSDBG_FATAL_FAILURE, "Unable to create TCURL request\n");
bb7cd1
-            talloc_zfree(tool_ctx);
bb7cd1
-            return 1;
bb7cd1
+    for (i = 0; requests[i] != NULL; i++) {
bb7cd1
+        req = tcurl_request_send(tmp_ctx, ev, tcurl_ctx, requests[i], 5);
bb7cd1
+        if (req == NULL) {
bb7cd1
+            DEBUG(SSSDBG_FATAL_FAILURE, "Could not create tevent request\n");
bb7cd1
+            ret = ENOMEM;
bb7cd1
+            goto done;
bb7cd1
         }
bb7cd1
 
bb7cd1
-        req = tcurl_request_send(tool_ctx, ev, ctx, tcurl_req, 10);
bb7cd1
-        if (ctx == NULL) {
bb7cd1
-            DEBUG(SSSDBG_FATAL_FAILURE, "Could not create request\n");
bb7cd1
-            talloc_zfree(tool_ctx);
bb7cd1
-            return 1;
bb7cd1
-        }
bb7cd1
         tevent_req_set_callback(req, request_done, tool_ctx);
bb7cd1
     }
bb7cd1
 
bb7cd1
@@ -226,11 +243,78 @@ int main(int argc, const char *argv[])
bb7cd1
     if (tool_ctx->nreqs > 0) {
bb7cd1
         DEBUG(SSSDBG_FATAL_FAILURE,
bb7cd1
               "The tool finished with some pending requests, fail!\n");
bb7cd1
-        talloc_zfree(tool_ctx);
bb7cd1
-        return 1;
bb7cd1
+        ret = EEXIST;
bb7cd1
+        goto done;
bb7cd1
     }
bb7cd1
 
bb7cd1
+    ret = EOK;
bb7cd1
+
bb7cd1
+done:
bb7cd1
+    talloc_free(tmp_ctx);
bb7cd1
+    return ret;
bb7cd1
+}
bb7cd1
+
bb7cd1
+int main(int argc, const char *argv[])
bb7cd1
+{
bb7cd1
+    struct tool_options opts = { 0 };
bb7cd1
+    struct tool_ctx *tool_ctx;
bb7cd1
+    struct tcurl_request **requests;
bb7cd1
+    poptContext pc;
bb7cd1
+    errno_t ret;
bb7cd1
+
bb7cd1
+    struct poptOption long_options[] = {
bb7cd1
+        POPT_AUTOHELP
bb7cd1
+        { "debug", '\0', POPT_ARG_INT, &opts.debug, 0, "The debug level to run with", NULL },
bb7cd1
+        { "socket-path", 's', POPT_ARG_STRING, &opts.socket_path, 0, "The path to the HTTP server socket", NULL },
bb7cd1
+        { "get", 'g', POPT_ARG_NONE, NULL, 'g', "Perform a HTTP GET (default)", NULL },
bb7cd1
+        { "put", 'p', POPT_ARG_NONE, NULL, 'p', "Perform a HTTP PUT", NULL },
bb7cd1
+        { "post", 'o', POPT_ARG_NONE, NULL, 'o', "Perform a HTTP POST", NULL },
bb7cd1
+        { "del", 'd', POPT_ARG_NONE, NULL, 'd', "Perform a HTTP DELETE", NULL },
bb7cd1
+        { "verbose", 'v', POPT_ARG_NONE, &opts.verbose, '\0', "Print response code and body", NULL },
bb7cd1
+        POPT_TABLEEND
bb7cd1
+    };
bb7cd1
+
bb7cd1
+    pc = poptGetContext(NULL, argc, argv, long_options, 0);
bb7cd1
+    poptSetOtherOptionHelp(pc, "[URL HTTPDATA]*");
bb7cd1
+
bb7cd1
+    tool_ctx = talloc_zero(NULL, struct tool_ctx);
bb7cd1
+    if (tool_ctx == NULL) {
bb7cd1
+        DEBUG(SSSDBG_CRIT_FAILURE, "Could not init tool context\n");
bb7cd1
+        ret = ENOMEM;
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = parse_options(pc, &opts);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE, "Unable to parse options [%d]: %s\n",
bb7cd1
+              ret, sss_strerror(ret));
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    DEBUG_CLI_INIT(opts.debug);
bb7cd1
+    tool_ctx->verbose = opts.verbose;
bb7cd1
+
bb7cd1
+    ret = prepare_requests(tool_ctx, pc, &opts, &requests, &tool_ctx->nreqs);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE, "Unable to prepare requests [%d]: %s\n",
bb7cd1
+              ret, sss_strerror(ret));
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = run_requests(tool_ctx, requests);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE, "Unable to issue requests [%d]: %s\n",
bb7cd1
+              ret, sss_strerror(ret));
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+done:
bb7cd1
     talloc_free(tool_ctx);
bb7cd1
     poptFreeContext(pc);
bb7cd1
-    return 0;
bb7cd1
+
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        return EXIT_FAILURE;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    return EXIT_SUCCESS;
bb7cd1
 }
bb7cd1
-- 
bb7cd1
2.9.3
bb7cd1