gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] branch master updated: add test for long polling on che


From: gnunet
Subject: [taler-merchant] branch master updated: add test for long polling on check-payment
Date: Sun, 10 Nov 2019 17:21:32 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new e9f8d26  add test for long polling on check-payment
e9f8d26 is described below

commit e9f8d268447dd2f1168a9189ec16e96c0fa3deec
Author: Christian Grothoff <address@hidden>
AuthorDate: Sun Nov 10 17:21:30 2019 +0100

    add test for long polling on check-payment
---
 src/include/taler_merchant_testing_lib.h |  36 ++++
 src/lib/test_merchant_api.c              |  14 +-
 src/lib/testing_api_cmd_check_payment.c  | 306 +++++++++++++++++++++++++++++--
 src/lib/testing_api_cmd_poll_payment.c   |   3 +-
 4 files changed, 337 insertions(+), 22 deletions(-)

diff --git a/src/include/taler_merchant_testing_lib.h 
b/src/include/taler_merchant_testing_lib.h
index ba0c927..30b1bdf 100644
--- a/src/include/taler_merchant_testing_lib.h
+++ b/src/include/taler_merchant_testing_lib.h
@@ -120,6 +120,42 @@ TALER_TESTING_cmd_check_payment (const char *label,
                                  const char *proposal_reference,
                                  unsigned int expect_paid);
 
+
+/**
+ * Make a "check payment" test command with long polling support.
+ *
+ * @param label command label.
+ * @param merchant_url merchant base url
+ * @param proposal_reference the proposal whose payment status
+ *        is going to be checked.
+ * @param timeout how long to wait during long polling for the reply
+ * @return the command
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_check_payment_start (const char *label,
+                                       const char *merchant_url,
+                                       const char *proposal_reference,
+                                       struct GNUNET_TIME_Relative timeout);
+
+
+/**
+ * Expect completion of a long-polled "check payment" test command.
+ *
+ * @param label command label.
+ * @param check_start_reference payment start operation that should have
+ *                   completed
+ * @param http_status expected HTTP response code.
+ * @param expect_paid #GNUNET_YES if we expect the proposal to be
+ *        paid, #GNUNET_NO otherwise.
+ * @return the command
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_check_payment_conclude (const char *label,
+                                          unsigned int http_status,
+                                          const char *poll_start_reference,
+                                          unsigned int expect_paid);
+
+
 /**
  * Start a long-polled "poll-payment" test command.
  *
diff --git a/src/lib/test_merchant_api.c b/src/lib/test_merchant_api.c
index 56cbb20..359f20d 100644
--- a/src/lib/test_merchant_api.c
+++ b/src/lib/test_merchant_api.c
@@ -295,6 +295,10 @@ run (void *cls,
                                           merchant_url,
                                           "create-proposal-1",
                                           GNUNET_TIME_UNIT_MINUTES),
+    TALER_TESTING_cmd_check_payment_start ("check-payment-2",
+                                           merchant_url,
+                                           "create-proposal-1",
+                                           GNUNET_TIME_UNIT_MINUTES),
     TALER_TESTING_cmd_pay ("deposit-simple",
                            merchant_url,
                            MHD_HTTP_OK,
@@ -307,12 +311,10 @@ run (void *cls,
                                              MHD_HTTP_OK,
                                              "poll-payment-2",
                                              GNUNET_YES),
-    TALER_TESTING_cmd_check_payment ("check-payment-2",
-                                     merchant_url,
-                                     MHD_HTTP_OK,
-                                     "create-proposal-1",
-                                     GNUNET_YES),
-
+    TALER_TESTING_cmd_check_payment_conclude ("check-payment-conclude-2",
+                                              MHD_HTTP_OK,
+                                              "check-payment-2",
+                                              GNUNET_YES),
     TALER_TESTING_cmd_pay_abort ("pay-abort-2",
                                  merchant_url,
                                  "deposit-simple",
diff --git a/src/lib/testing_api_cmd_check_payment.c 
b/src/lib/testing_api_cmd_check_payment.c
index 2e988d7..c879b78 100644
--- a/src/lib/testing_api_cmd_check_payment.c
+++ b/src/lib/testing_api_cmd_check_payment.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2018 Taler Systems SA
+  Copyright (C) 2014-2019 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as
@@ -16,7 +16,6 @@
   License along with TALER; see the file COPYING.  If not, see
   <http://www.gnu.org/licenses/>
 */
-
 /**
  * @file lib/testing_api_cmd_check_payment.c
  * @brief command to test the /check-payment feature.
@@ -30,6 +29,11 @@
 #include "taler_merchant_testing_lib.h"
 
 
+/**
+ * State for a /check-payment conclude CMD.
+ */
+struct CheckPaymentConcludeState;
+
 /**
  * State for a /check-payment CMD.
  */
@@ -47,9 +51,9 @@ struct CheckPaymentState
   struct TALER_TESTING_Interpreter *is;
 
   /**
-   * Expected HTTP response status code.
+   * The merchant base URL.
    */
-  unsigned int http_status;
+  const char *merchant_url;
 
   /**
    * Reference to a command that can provide a order id,
@@ -58,14 +62,79 @@ struct CheckPaymentState
   const char *proposal_reference;
 
   /**
-   * GNUNET_YES if we expect the proposal was paid.
+   * State for a /check-payment conclude CMD.
+ */
+  struct CheckPaymentConcludeState *cs;
+
+  /**
+   * 0 if long-polling is not desired.
    */
-  unsigned int expect_paid;
+  struct GNUNET_TIME_Relative timeout;
 
   /**
-   * The merchant base URL.
+   * Set to the start time of the @e cpo plus the @e timeout.
    */
-  const char *merchant_url;
+  struct GNUNET_TIME_Absolute deadline;
+
+  /**
+   * #GNUNET_YES if we expect the proposal was paid, synchronous variant.
+   */
+  int expect_paid;
+
+  /**
+   * #GNUNET_YES if the proposal was paid.
+   */
+  int paid;
+
+  /**
+   * #GNUNET_YES if the proposal was paid and then refunded
+   */
+  int refunded;
+
+  /**
+   * Observed HTTP response status code.
+   */
+  unsigned int http_status;
+
+  /**
+   * Expected HTTP response status code, synchronous variant.
+   */
+  unsigned int expected_http_status;
+
+};
+
+
+/**
+ * State for a /check-payment conclude CMD.
+ */
+struct CheckPaymentConcludeState
+{
+
+  /**
+   * The interpreter state.
+   */
+  struct TALER_TESTING_Interpreter *is;
+
+  /**
+   * Reference to a command that can provide a check payment start command.
+   */
+  const char *start_reference;
+
+  /**
+   * Task to wait for the deadline.
+   */
+  struct GNUNET_SCHEDULER_Task *task;
+
+  /**
+   * Expected HTTP response status code.
+   */
+  unsigned int expected_http_status;
+
+  /**
+   * #GNUNET_YES if the proposal was expected to be paid.
+   */
+  int expected_paid;
+
 };
 
 
@@ -94,6 +163,64 @@ check_payment_cleanup (void *cls,
 }
 
 
+/**
+ * Task called when either the timeout for the /check-payment
+ * command expired or we got a response.  Checks if the
+ * result is what we expected.
+ *
+ * @param cls a `struct CheckPaymentConcludeState`
+ */
+static void
+conclude_task (void *cls)
+{
+  struct CheckPaymentConcludeState *cpc = cls;
+  const struct TALER_TESTING_Command *check_cmd;
+  struct CheckPaymentState *cps;
+  struct GNUNET_TIME_Absolute now;
+
+  cpc->task = NULL;
+  check_cmd =
+    TALER_TESTING_interpreter_lookup_command (cpc->is,
+                                              cpc->start_reference);
+  cps = check_cmd->cls;
+  if (NULL != cps->cpo)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Expected /poll/payment to have completed, but it did not!\n");
+    TALER_TESTING_FAIL (cpc->is);
+  }
+  if (cps->http_status != cpc->expected_http_status)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Expected HTTP status %u, got %u\n",
+                cpc->expected_http_status,
+                cps->http_status);
+    TALER_TESTING_FAIL (cps->is);
+  }
+  now = GNUNET_TIME_absolute_get ();
+  if ( (GNUNET_NO == cps->paid) &&
+       (GNUNET_TIME_absolute_add (cps->deadline,
+                                  GNUNET_TIME_UNIT_SECONDS).abs_value_us <
+        now.abs_value_us) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Expected answer to be delayed until %llu, but got response at 
%llu\n",
+                (unsigned long long) cps->deadline.abs_value_us,
+                (unsigned long long) now.abs_value_us);
+    TALER_TESTING_FAIL (cps->is);
+  }
+  if (cps->paid != cpc->expected_paid)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Expected paid status %u, got %u\n",
+                cpc->expected_paid,
+                cps->paid);
+    TALER_TESTING_FAIL (cps->is);
+  }
+  TALER_TESTING_interpreter_next (cps->is);
+}
+
+
 /**
  * Callback for a /check-payment request.
  *
@@ -127,11 +254,28 @@ check_payment_cb (void *cls,
               cps->expect_paid,
               paid,
               taler_pay_uri);
-  if (paid != cps->expect_paid)
-    TALER_TESTING_FAIL (cps->is);
-  if (cps->http_status != http_status)
-    TALER_TESTING_FAIL (cps->is);
-  TALER_TESTING_interpreter_next (cps->is);
+  cps->paid = paid;
+  cps->http_status = http_status;
+  cps->refunded = refunded;
+  if (0 == cps->timeout.rel_value_us)
+  {
+    /* synchronous variant */
+    if (paid != cps->expect_paid)
+      TALER_TESTING_FAIL (cps->is);
+    if (cps->http_status != http_status)
+      TALER_TESTING_FAIL (cps->is);
+    TALER_TESTING_interpreter_next (cps->is);
+  }
+  else
+  {
+    /* asynchronous variant */
+    if (NULL != cps->cs)
+    {
+      GNUNET_SCHEDULER_cancel (cps->cs->task);
+      cps->cs->task = GNUNET_SCHEDULER_add_now (&conclude_task,
+                                                cps->cs);
+    }
+  }
 }
 
 
@@ -166,10 +310,12 @@ check_payment_run (void *cls,
                                            cps->merchant_url,
                                            order_id,
                                            NULL,
-                                           GNUNET_TIME_UNIT_ZERO,
+                                           cps->timeout,
                                            &check_payment_cb,
                                            cps);
   GNUNET_assert (NULL != cps->cpo);
+  if (0 != cps->timeout.rel_value_us)
+    TALER_TESTING_interpreter_next (cps->is);
 }
 
 
@@ -195,7 +341,7 @@ TALER_TESTING_cmd_check_payment (const char *label,
   struct CheckPaymentState *cps;
 
   cps = GNUNET_new (struct CheckPaymentState);
-  cps->http_status = http_status;
+  cps->expected_http_status = http_status;
   cps->proposal_reference = proposal_reference;
   cps->expect_paid = expect_paid;
   cps->merchant_url = merchant_url;
@@ -212,4 +358,134 @@ TALER_TESTING_cmd_check_payment (const char *label,
 }
 
 
+/**
+ * Make a "check payment" test command with long polling support.
+ *
+ * @param label command label.
+ * @param merchant_url merchant base url
+ * @param proposal_reference the proposal whose payment status
+ *        is going to be checked.
+ * @param timeout how long to wait during long polling for the reply
+ * @return the command
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_check_payment_start (const char *label,
+                                       const char *merchant_url,
+                                       const char *proposal_reference,
+                                       struct GNUNET_TIME_Relative timeout)
+{
+  struct CheckPaymentState *cps;
+
+  if (0 == timeout.rel_value_us)
+    timeout.rel_value_us = 1; /* 0 reserved for blocking version */
+  cps = GNUNET_new (struct CheckPaymentState);
+  cps->timeout = timeout;
+  cps->proposal_reference = proposal_reference;
+  cps->merchant_url = merchant_url;
+  {
+    struct TALER_TESTING_Command cmd = {
+      .cls = cps,
+      .label = label,
+      .run = &check_payment_run,
+      .cleanup = &check_payment_cleanup
+    };
+
+    return cmd;
+  }
+}
+
+
+/**
+ * Free a /check-payment conclusion CMD, and possibly cancel a pending
+ * operation thereof.
+ *
+ * @param cls closure
+ * @param cmd the command currently getting freed.
+ */
+static void
+check_payment_conclude_cleanup (void *cls,
+                                const struct TALER_TESTING_Command *cmd)
+{
+  struct CheckPaymentConcludeState *cps = cls;
+
+  if (NULL != cps->task)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Command `%s' was not terminated\n",
+                TALER_TESTING_interpreter_get_current_label (
+                  cps->is));
+    GNUNET_SCHEDULER_cancel (cps->task);
+    cps->task = NULL;
+  }
+}
+
+
+/**
+ * Run a /check-payment conclusion CMD.
+ *
+ * @param cmd the command currenly being run.
+ * @param cls closure.
+ * @param is interpreter state.
+ */
+static void
+check_payment_conclude_run (void *cls,
+                            const struct TALER_TESTING_Command *cmd,
+                            struct TALER_TESTING_Interpreter *is)
+{
+  struct CheckPaymentConcludeState *cpc = cls;
+  const struct TALER_TESTING_Command *check_cmd;
+  struct CheckPaymentState *cps;
+
+  cpc->is = is;
+  check_cmd =
+    TALER_TESTING_interpreter_lookup_command (is,
+                                              cpc->start_reference);
+  GNUNET_assert (check_cmd->run == &check_payment_run);
+  cps = check_cmd->cls;
+  if (NULL == cps->cpo)
+    cpc->task = GNUNET_SCHEDULER_add_now (&conclude_task,
+                                          cpc);
+  else
+    cpc->task = GNUNET_SCHEDULER_add_at (cps->deadline,
+                                         &conclude_task,
+                                         cpc);
+}
+
+
+/**
+ * Expect completion of a long-polled "check payment" test command.
+ *
+ * @param label command label.
+ * @param check_start_reference payment start operation that should have
+ *                   completed
+ * @param http_status expected HTTP response code.
+ * @param expect_paid #GNUNET_YES if we expect the proposal to be
+ *        paid, #GNUNET_NO otherwise.
+ * @return the command
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_check_payment_conclude (const char *label,
+                                          unsigned int http_status,
+                                          const char *poll_start_reference,
+                                          unsigned int expect_paid)
+{
+  struct CheckPaymentConcludeState *cps;
+
+  cps = GNUNET_new (struct CheckPaymentConcludeState);
+  cps->start_reference = poll_start_reference;
+  cps->expected_paid = expect_paid;
+  cps->expected_http_status = http_status;
+  {
+    struct TALER_TESTING_Command cmd = {
+      .cls = cps,
+      .label = label,
+      .run = &check_payment_conclude_run,
+      .cleanup = &check_payment_conclude_cleanup
+    };
+
+    return cmd;
+  }
+}
+
+
 /* end of testing_api_cmd_check_payment.c */
diff --git a/src/lib/testing_api_cmd_poll_payment.c 
b/src/lib/testing_api_cmd_poll_payment.c
index c6200fb..40bc79e 100644
--- a/src/lib/testing_api_cmd_poll_payment.c
+++ b/src/lib/testing_api_cmd_poll_payment.c
@@ -268,7 +268,7 @@ poll_payment_cb (void *cls,
   cps->paid = paid;
   cps->http_status = http_status;
   cps->refunded = refunded;
-  if (refunded)
+  if (GNUNET_YES == refunded)
     cps->refund = *refund_amount;
   if (NULL != cps->cs)
   {
@@ -415,6 +415,7 @@ poll_payment_conclude_run (void *cls,
   poll_cmd =
     TALER_TESTING_interpreter_lookup_command (is,
                                               ppc->start_reference);
+  GNUNET_assert (poll_cmd->run == &poll_payment_start_run);
   cps = poll_cmd->cls;
   if (NULL == cps->cpo)
     ppc->task = GNUNET_SCHEDULER_add_now (&conclude_task,

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]