Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2018 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it
6 : under the terms of the GNU General Public License as published by
7 : the Free Software Foundation; either version 3, or (at your
8 : option) any later version.
9 :
10 : TALER is distributed in the hope that it will be useful, but
11 : WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : General Public License for more details.
14 :
15 : You should have received a copy of the GNU General Public
16 : License along with TALER; see the file COPYING. If not, see
17 : <http://www.gnu.org/licenses/>
18 : */
19 : /**
20 : * @file testing/testing_api_cmd_wire.c
21 : * @brief command for testing /wire.
22 : * @author Marcello Stanisci
23 : */
24 : #include "platform.h"
25 : #include "taler_json_lib.h"
26 : #include <gnunet/gnunet_curl_lib.h>
27 : #include "taler_testing_lib.h"
28 :
29 :
30 : /**
31 : * State for a "wire" CMD.
32 : */
33 : struct WireState
34 : {
35 :
36 : /**
37 : * Handle to the /wire operation.
38 : */
39 : struct TALER_EXCHANGE_WireHandle *wh;
40 :
41 : /**
42 : * Which wire-method we expect is offered by the exchange.
43 : */
44 : const char *expected_method;
45 :
46 : /**
47 : * Flag indicating if the expected method is actually
48 : * offered.
49 : */
50 : unsigned int method_found;
51 :
52 : /**
53 : * Fee we expect is charged for this wire-transfer method.
54 : */
55 : const char *expected_fee;
56 :
57 : /**
58 : * Expected HTTP response code.
59 : */
60 : unsigned int expected_response_code;
61 :
62 : /**
63 : * Interpreter state.
64 : */
65 : struct TALER_TESTING_Interpreter *is;
66 : };
67 :
68 :
69 : /**
70 : * Check whether the HTTP response code is acceptable, that
71 : * the expected wire method is offered by the exchange, and
72 : * that the wire fee is acceptable too.
73 : *
74 : * @param cls closure.
75 : * @param hr HTTP response details
76 : * @param accounts_len length of the @a accounts array.
77 : * @param accounts list of wire accounts of the exchange,
78 : * NULL on error.
79 : */
80 : static void
81 0 : wire_cb (void *cls,
82 : const struct TALER_EXCHANGE_HttpResponse *hr,
83 : unsigned int accounts_len,
84 : const struct TALER_EXCHANGE_WireAccount *accounts)
85 : {
86 0 : struct WireState *ws = cls;
87 0 : struct TALER_TESTING_Command *cmd = &ws->is->commands[ws->is->ip];
88 : struct TALER_Amount expected_fee;
89 :
90 0 : TALER_LOG_DEBUG ("Checking parsed /wire response\n");
91 0 : ws->wh = NULL;
92 0 : if (ws->expected_response_code != hr->http_status)
93 : {
94 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
95 : "Received unexpected status code %u\n",
96 : hr->http_status);
97 0 : TALER_TESTING_interpreter_fail (ws->is);
98 0 : return;
99 : }
100 :
101 0 : if (MHD_HTTP_OK == hr->http_status)
102 : {
103 0 : for (unsigned int i = 0; i<accounts_len; i++)
104 : {
105 : char *method;
106 :
107 0 : method = TALER_payto_get_method (accounts[i].payto_uri);
108 0 : if (0 == strcmp (ws->expected_method,
109 : method))
110 : {
111 0 : ws->method_found = GNUNET_OK;
112 0 : if (NULL != ws->expected_fee)
113 : {
114 0 : GNUNET_assert (GNUNET_OK ==
115 : TALER_string_to_amount (ws->expected_fee,
116 : &expected_fee));
117 0 : for (const struct TALER_EXCHANGE_WireAggregateFees *waf
118 0 : = accounts[i].fees;
119 : NULL != waf;
120 0 : waf = waf->next)
121 : {
122 0 : if (0 != TALER_amount_cmp (&waf->fees.wire,
123 : &expected_fee))
124 : {
125 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
126 : "Wire fee mismatch to command %s\n",
127 : cmd->label);
128 0 : TALER_TESTING_interpreter_fail (ws->is);
129 0 : GNUNET_free (method);
130 0 : return;
131 : }
132 : }
133 : }
134 : }
135 0 : TALER_LOG_DEBUG ("Freeing method '%s'\n",
136 : method);
137 0 : GNUNET_free (method);
138 : }
139 0 : if (GNUNET_OK != ws->method_found)
140 : {
141 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
142 : "/wire does not offer method '%s'\n",
143 : ws->expected_method);
144 0 : TALER_TESTING_interpreter_fail (ws->is);
145 0 : return;
146 : }
147 : }
148 0 : TALER_TESTING_interpreter_next (ws->is);
149 : }
150 :
151 :
152 : /**
153 : * Run the command.
154 : *
155 : * @param cls closure.
156 : * @param cmd the command to execute.
157 : * @param is the interpreter state.
158 : */
159 : static void
160 0 : wire_run (void *cls,
161 : const struct TALER_TESTING_Command *cmd,
162 : struct TALER_TESTING_Interpreter *is)
163 : {
164 0 : struct WireState *ws = cls;
165 :
166 : (void) cmd;
167 0 : ws->is = is;
168 0 : ws->wh = TALER_EXCHANGE_wire (is->exchange,
169 : &wire_cb,
170 : ws);
171 0 : }
172 :
173 :
174 : /**
175 : * Cleanup the state of a "wire" CMD, and possibly cancel a
176 : * pending operation thereof.
177 : *
178 : * @param cls closure.
179 : * @param cmd the command which is being cleaned up.
180 : */
181 : static void
182 0 : wire_cleanup (void *cls,
183 : const struct TALER_TESTING_Command *cmd)
184 : {
185 0 : struct WireState *ws = cls;
186 :
187 0 : if (NULL != ws->wh)
188 : {
189 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
190 : "Command %u (%s) did not complete\n",
191 : ws->is->ip,
192 : cmd->label);
193 0 : TALER_EXCHANGE_wire_cancel (ws->wh);
194 0 : ws->wh = NULL;
195 : }
196 0 : GNUNET_free (ws);
197 0 : }
198 :
199 :
200 : /**
201 : * Create a "wire" command.
202 : *
203 : * @param label the command label.
204 : * @param expected_method which wire-transfer method is expected
205 : * to be offered by the exchange.
206 : * @param expected_fee the fee the exchange should charge.
207 : * @param expected_response_code the HTTP response the exchange
208 : * should return.
209 : * @return the command.
210 : */
211 : struct TALER_TESTING_Command
212 0 : TALER_TESTING_cmd_wire (const char *label,
213 : const char *expected_method,
214 : const char *expected_fee,
215 : unsigned int expected_response_code)
216 : {
217 : struct WireState *ws;
218 :
219 0 : ws = GNUNET_new (struct WireState);
220 0 : ws->expected_method = expected_method;
221 0 : ws->expected_fee = expected_fee;
222 0 : ws->expected_response_code = expected_response_code;
223 : {
224 0 : struct TALER_TESTING_Command cmd = {
225 : .cls = ws,
226 : .label = label,
227 : .run = &wire_run,
228 : .cleanup = &wire_cleanup
229 : };
230 :
231 0 : return cmd;
232 : }
233 : }
|