summaryrefslogtreecommitdiff
path: root/src/testing/testing_api_cmd_history.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing/testing_api_cmd_history.c')
-rw-r--r--src/testing/testing_api_cmd_history.c359
1 files changed, 359 insertions, 0 deletions
diff --git a/src/testing/testing_api_cmd_history.c b/src/testing/testing_api_cmd_history.c
new file mode 100644
index 00000000..dabbf3cc
--- /dev/null
+++ b/src/testing/testing_api_cmd_history.c
@@ -0,0 +1,359 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2014-2018 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
+ published by the Free Software Foundation; either version 3, or
+ (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with TALER; see the file COPYING. If not, see
+ <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file lib/testing_api_cmd_history.c
+ * @brief command to test the /history API.
+ * @author Marcello Stanisci
+ */
+
+#include "platform.h"
+#include <taler/taler_exchange_service.h>
+#include <taler/taler_testing_lib.h>
+#include "taler_merchant_service.h"
+#include "taler_merchant_testing_lib.h"
+
+
+/**
+ * State for a "history" CMD.
+ */
+struct HistoryState
+{
+
+ /**
+ * Expected status code.
+ */
+ unsigned int http_status;
+
+ /**
+ * URL of the merchant backend serving the /history request.
+ */
+ const char *merchant_url;
+
+ /**
+ * The interpreter state.
+ */
+ struct TALER_TESTING_Interpreter *is;
+
+ /**
+ * Handle to the /history operation.
+ */
+ struct TALER_MERCHANT_HistoryOperation *ho;
+
+ /**
+ * Only history entries younger than this
+ * value will be returned.
+ */
+ struct GNUNET_TIME_Absolute time;
+
+ /**
+ * First row index we want in the results.
+ */
+ unsigned long long start;
+
+ /**
+ * When this flag is GNUNET_YES, then the interpreter
+ * will request /history *omitting* the 'start' URL argument.
+ */
+ int use_default_start;
+
+ /**
+ * How many rows we want the response to contain, at most.
+ */
+ long long nrows;
+
+ /**
+ * Expected number of history entries returned by the
+ * backend.
+ */
+ unsigned int nresult;
+};
+
+
+/**
+ * Callback for a /history request; checks that (1) HTTP status
+ * is expected, the number of rows returned is expected, and that
+ * the rows are sorted from the youngest to the oldest record.
+ *
+ * @param cls closure
+ * @param hr HTTP response we got
+ */
+static void
+history_cb (void *cls,
+ const struct TALER_MERCHANT_HttpResponse *hr)
+{
+ struct HistoryState *hs = cls;
+ unsigned int nresult;
+ struct GNUNET_TIME_Absolute last_timestamp;
+ struct GNUNET_TIME_Absolute entry_timestamp;
+ json_t *arr;
+
+ hs->ho = NULL;
+
+ if (hs->http_status != hr->http_status)
+ TALER_TESTING_FAIL (hs->is);
+
+ if (MHD_HTTP_OK != hs->http_status)
+ {
+ /* move on without further checking. */
+ TALER_TESTING_interpreter_next (hs->is);
+ return;
+ }
+
+ arr = json_object_get (hr->reply,
+ "history");
+ nresult = json_array_size (arr);
+ if (hs->nresult != nresult)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected number of history entries: Got %d, expected %d\n",
+ nresult,
+ hs->nresult);
+ TALER_TESTING_FAIL (hs->is);
+ }
+
+ last_timestamp = GNUNET_TIME_absolute_get ();
+ last_timestamp = GNUNET_TIME_absolute_add (last_timestamp,
+ GNUNET_TIME_UNIT_DAYS);
+ {
+ json_t *entry;
+ size_t index;
+ json_array_foreach (arr, index, entry)
+ {
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_absolute_time ("timestamp",
+ &entry_timestamp),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (entry,
+ spec,
+ NULL, NULL))
+ TALER_TESTING_FAIL (hs->is);
+ if (last_timestamp.abs_value_us < entry_timestamp.abs_value_us)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "History entries are NOT sorted from younger to older\n");
+ TALER_TESTING_interpreter_fail (hs->is);
+ return;
+ }
+ last_timestamp = entry_timestamp;
+ }
+ }
+ TALER_TESTING_interpreter_next (hs->is);
+}
+
+
+/**
+ * Free the state for a "history" CMD, and possibly cancel
+ * any pending operation thereof.
+ *
+ * @param cls closure
+ * @param cmd command being freed now.
+ */
+static void
+history_cleanup (void *cls,
+ const struct TALER_TESTING_Command *cmd)
+{
+ struct HistoryState *hs = cls;
+
+ if (NULL != hs->ho)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "/history operation did not complete\n");
+ TALER_MERCHANT_history_cancel (hs->ho);
+ }
+ GNUNET_free (hs);
+}
+
+
+/**
+ * Run a "history" CMD.
+ *
+ * @param cls closure.
+ * @param cmd current command.
+ * @param is interpreter state.
+ */
+static void
+history_run (void *cls,
+ const struct TALER_TESTING_Command *cmd,
+ struct TALER_TESTING_Interpreter *is)
+{
+ struct HistoryState *hs = cls;
+
+ hs->is = is;
+ if (0 == hs->time.abs_value_us)
+ {
+ hs->time = GNUNET_TIME_absolute_add
+ (GNUNET_TIME_absolute_get (),
+ GNUNET_TIME_UNIT_HOURS);
+ GNUNET_TIME_round_abs (&hs->time);
+ }
+
+ switch (hs->use_default_start)
+ {
+ case GNUNET_YES:
+ hs->ho = TALER_MERCHANT_history_default_start
+ (is->ctx,
+ hs->merchant_url,
+ hs->nrows,
+ hs->time,
+ &history_cb,
+ hs);
+ break;
+
+ case GNUNET_NO:
+ hs->ho = TALER_MERCHANT_history (is->ctx,
+ hs->merchant_url,
+ hs->start,
+ hs->nrows,
+ hs->time,
+ &history_cb,
+ hs);
+ break;
+ default:
+ TALER_LOG_ERROR ("Bad value for 'use_default_start'\n");
+ TALER_TESTING_FAIL (is);
+ }
+
+ if (NULL == hs->ho)
+ TALER_TESTING_FAIL (is);
+}
+
+
+/**
+ * Make a "history" command.
+ *
+ * @param label command label.
+ * @param merchant_url base URL of the merchant serving the
+ * request.
+ * @param ctx CURL context.
+ * @param http_status expected HTTP response code
+ * @param time limit towards the past for the history
+ * records we want returned.
+ * @param nresult how many results are expected
+ * @param start first row id we want in the result.
+ * @param use_default_start if GNUNET_YES, then it will
+ * use the API call that requests /history omitting
+ * the 'start' argument. This makes easier to test
+ * the server default behaviour.
+ * @param nrows how many row we want to receive, at most.
+ */
+static struct TALER_TESTING_Command
+cmd_history2 (const char *label,
+ const char *merchant_url,
+ unsigned int http_status,
+ struct GNUNET_TIME_Absolute time,
+ unsigned int nresult,
+ unsigned long long start,
+ int use_default_start,
+ long long nrows)
+{
+ struct HistoryState *hs;
+
+ hs = GNUNET_new (struct HistoryState);
+ hs->http_status = http_status;
+ hs->time = time;
+ hs->nresult = nresult;
+ hs->start = start;
+ hs->nrows = nrows;
+ hs->merchant_url = merchant_url;
+ hs->use_default_start = use_default_start;
+ {
+ struct TALER_TESTING_Command cmd = {
+ .cls = hs,
+ .label = label,
+ .run = &history_run,
+ .cleanup = &history_cleanup
+ };
+
+ return cmd;
+ }
+}
+
+
+/**
+ * Make a "history" command.
+ *
+ * @param label command label.
+ * @param merchant_url base URL of the merchant serving the
+ * request.
+ * @param ctx CURL context.
+ * @param http_status expected HTTP response code
+ * @param time limit towards the past for the history
+ * records we want returned.
+ * @param nresult how many results are expected
+ * @param nrows how many row we want to receive, at most.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_history_default_start
+ (const char *label,
+ const char *merchant_url,
+ unsigned int http_status,
+ struct GNUNET_TIME_Absolute time,
+ unsigned int nresult,
+ long long nrows)
+{
+ return cmd_history2 (label,
+ merchant_url,
+ http_status,
+ time,
+ nresult,
+ -1, /* ignored */
+ GNUNET_YES,
+ nrows);
+}
+
+
+/**
+ * Make a "history" command.
+ *
+ * @param label command label.
+ * @param merchant_url base URL of the merchant serving the
+ * request.
+ * @param ctx CURL context.
+ * @param http_status expected HTTP response code
+ * @param time limit towards the past for the history
+ * records we want returned.
+ * @param nresult how many results are expected
+ * @param start first row id we want in the result.
+ * @param nrows how many row we want to receive, at most.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_history (const char *label,
+ const char *merchant_url,
+ unsigned int http_status,
+ struct GNUNET_TIME_Absolute time,
+ unsigned int nresult,
+ unsigned long long start,
+ long long nrows)
+{
+ return cmd_history2 (label,
+ merchant_url,
+ http_status,
+ time,
+ nresult,
+ start,
+ GNUNET_NO,
+ nrows);
+}
+
+
+/* end of testing_api_cmd_history.c */