diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-10-18 15:13:59 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-10-18 15:13:59 +0000 |
commit | 96ccef162f276c2f40b09ceca59c982bbaa3709e (patch) | |
tree | a10a4fe26bfd70a9cc08359b68195a5f5d729c0c /src/scalarproduct | |
parent | 8fe29d55719cb024f2e162f1f5289ded8cf91e53 (diff) | |
download | gnunet-96ccef162f276c2f40b09ceca59c982bbaa3709e.tar.gz gnunet-96ccef162f276c2f40b09ceca59c982bbaa3709e.zip |
added testcase for negative scalarproducts
added testcase for negative-zero scalarproducts
Diffstat (limited to 'src/scalarproduct')
-rwxr-xr-x | src/scalarproduct/test_scalarproduct.sh | 11 | ||||
-rw-r--r-- | src/scalarproduct/test_scalarproduct_api.c | 865 | ||||
-rwxr-xr-x | src/scalarproduct/test_scalarproduct_negative.sh | 49 | ||||
-rwxr-xr-x | src/scalarproduct/test_scalarproduct_negativezero.sh | 49 |
4 files changed, 102 insertions, 872 deletions
diff --git a/src/scalarproduct/test_scalarproduct.sh b/src/scalarproduct/test_scalarproduct.sh index 5f335db3c..82b42e992 100755 --- a/src/scalarproduct/test_scalarproduct.sh +++ b/src/scalarproduct/test_scalarproduct.sh | |||
@@ -1,8 +1,8 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | # compute a simple scalar product | 2 | # compute a simple scalar product |
3 | # payload for this test: | 3 | # payload for this test: |
4 | INPUTALICE="-k AAAA -e 3,3,-1" | 4 | INPUTALICE="-k CCC -e 3,3,-1" |
5 | INPUTBOB="-k AAAA -e 1000,100,24" | 5 | INPUTBOB="-k CCC -e 1000,100,24" |
6 | 6 | ||
7 | # necessary to make the testing prefix deterministic, so we can access the config files | 7 | # necessary to make the testing prefix deterministic, so we can access the config files |
8 | PREFIX=/tmp/test-scalarproduct`date +%H%M%S` | 8 | PREFIX=/tmp/test-scalarproduct`date +%H%M%S` |
@@ -18,16 +18,13 @@ CFGBOB="-c $PREFIX/1/config" | |||
18 | # thus redirecting stdin does not suffice) | 18 | # thus redirecting stdin does not suffice) |
19 | GNUNET_LOG='scalarproduct;;;;DEBUG' GNUNET_TESTING_PREFIX=$PREFIX ../testbed/gnunet-testbed-profiler -n -c test_scalarproduct.conf -p 2 2>service.log & | 19 | GNUNET_LOG='scalarproduct;;;;DEBUG' GNUNET_TESTING_PREFIX=$PREFIX ../testbed/gnunet-testbed-profiler -n -c test_scalarproduct.conf -p 2 2>service.log & |
20 | PID=$! | 20 | PID=$! |
21 | |||
22 | echo $PID | ||
23 | read | ||
24 | sleep 5 | 21 | sleep 5 |
22 | |||
25 | # get bob's peer ID, necessary for alice | 23 | # get bob's peer ID, necessary for alice |
26 | PEERIDBOB=`gnunet-peerinfo -qs $CFGBOB` | 24 | PEERIDBOB=`gnunet-peerinfo -qs $CFGBOB` |
27 | 25 | ||
28 | GNUNET_LOG='scalarproduct;;;;DEBUG' gnunet-scalarproduct $CFGBOB $INPUTBOB 2>bob.log & | 26 | GNUNET_LOG='scalarproduct;;;;DEBUG' gnunet-scalarproduct $CFGBOB $INPUTBOB 2>bob.log & |
29 | RESULT=`GNUNET_LOG='scalarproduct;;;;DEBUG' gnunet-scalarproduct $CFGALICE $INPUTALICE -p $PEERIDBOB 2>alice.log` | 27 | RESULT=`GNUNET_LOG='scalarproduct;;;;DEBUG' gnunet-scalarproduct $CFGALICE $INPUTALICE -p $PEERIDBOB 2>alice.log` |
30 | RESULT=`printf "%X\n" "0x$RESULT"` | ||
31 | 28 | ||
32 | cat alice.log bob.log service.log >> test_scalarproduct.log | 29 | cat alice.log bob.log service.log >> test_scalarproduct.log |
33 | rm -f alice.log bob.log service.log | 30 | rm -f alice.log bob.log service.log |
@@ -36,7 +33,7 @@ ISSUES=$((`grep scalarproduct test_scalarproduct.log | grep -c ERROR` + `grep sc | |||
36 | # terminate the testbed | 33 | # terminate the testbed |
37 | kill $PID | 34 | kill $PID |
38 | 35 | ||
39 | EXPECTED="CCC" | 36 | EXPECTED="0CCC" |
40 | if [ "$ISSUES" -eq "0" ] | 37 | if [ "$ISSUES" -eq "0" ] |
41 | then | 38 | then |
42 | if [ "$RESULT" == "$EXPECTED" ] | 39 | if [ "$RESULT" == "$EXPECTED" ] |
diff --git a/src/scalarproduct/test_scalarproduct_api.c b/src/scalarproduct/test_scalarproduct_api.c deleted file mode 100644 index 082723278..000000000 --- a/src/scalarproduct/test_scalarproduct_api.c +++ /dev/null | |||
@@ -1,865 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet 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 License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * Aim of test_scalarproduct_api : This test creates two peers. Peer1 is the | ||
23 | * responder peer, Bob and Peer2 is the initiator peer, Alice. Both peers | ||
24 | * connect to VectorProduct Service, and use the API to issue requests to | ||
25 | * service. Test passes, when the expected scalar product is received from the | ||
26 | * service. | ||
27 | */ | ||
28 | |||
29 | /** | ||
30 | * @file scalarproduct/testbed_scalarproduct_api.c | ||
31 | * @brief VectorProduct API testing between 4 peers using testing API | ||
32 | * @author Gaurav Kukreja | ||
33 | * @author Christian Fuchs | ||
34 | */ | ||
35 | |||
36 | #include <string.h> | ||
37 | |||
38 | #include <inttypes.h> | ||
39 | #include "platform.h" | ||
40 | #include "gnunet_util_lib.h" | ||
41 | #include "gnunet_testbed_service.h" | ||
42 | #include "gnunet_common.h" | ||
43 | #include "gnunet_scalarproduct_service.h" | ||
44 | #include "gnunet_protocols.h" | ||
45 | |||
46 | #define NUM_PEERS 2 | ||
47 | |||
48 | #define LOG(kind,...) GNUNET_log_from (kind, "test-scalarproduct-api",__VA_ARGS__) | ||
49 | |||
50 | /** | ||
51 | * Structure for holding peer's sockets and IO Handles | ||
52 | */ | ||
53 | struct PeerData | ||
54 | { | ||
55 | /** | ||
56 | * Handle to testbed peer | ||
57 | */ | ||
58 | struct GNUNET_TESTBED_Peer *peer; | ||
59 | |||
60 | /** | ||
61 | * The service connect operation to stream | ||
62 | */ | ||
63 | struct GNUNET_TESTBED_Operation *op; | ||
64 | |||
65 | /** | ||
66 | * Our Peer id | ||
67 | */ | ||
68 | struct GNUNET_PeerIdentity our_id; | ||
69 | |||
70 | /** | ||
71 | * Pointer to Vector Product Handle | ||
72 | */ | ||
73 | struct GNUNET_SCALARPRODUCT_Handle *vh; | ||
74 | }; | ||
75 | |||
76 | /** | ||
77 | * Different states in test setup | ||
78 | */ | ||
79 | enum SetupState | ||
80 | { | ||
81 | /** | ||
82 | * Get the identity of peer 1 | ||
83 | */ | ||
84 | PEER1_GET_IDENTITY, | ||
85 | |||
86 | /** | ||
87 | * Get the identity of peer 2 | ||
88 | */ | ||
89 | PEER2_GET_IDENTITY, | ||
90 | |||
91 | /** | ||
92 | * Connect to stream service of peer 1 | ||
93 | */ | ||
94 | PEER1_SCALARPRODUCT_CONNECT, | ||
95 | |||
96 | /** | ||
97 | * Connect to stream service of peer 2 | ||
98 | */ | ||
99 | PEER2_SCALARPRODUCT_CONNECT | ||
100 | |||
101 | }; | ||
102 | |||
103 | /****************************************************************************** | ||
104 | *** Global Variables ***************************** | ||
105 | ******************************************************************************/ | ||
106 | |||
107 | /** | ||
108 | * Maximum allowed message-ids we can check in one go (with one GNUNET_message) | ||
109 | */ | ||
110 | static unsigned int max_mids; | ||
111 | |||
112 | /** | ||
113 | * Session Key used by both the test peers | ||
114 | */ | ||
115 | char input_key[103] = "helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhe"; | ||
116 | |||
117 | /** | ||
118 | * Input elements for peer1 | ||
119 | */ | ||
120 | char input_elements_peer1[] = "11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11"; | ||
121 | //char input_elements_peer1[] = "11,11,11"; | ||
122 | |||
123 | /** | ||
124 | * Input Mask for peer 1 | ||
125 | */ | ||
126 | char input_mask_peer1[] = "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"; | ||
127 | //char input_mask_peer1[] = "1,1,1"; | ||
128 | |||
129 | /** | ||
130 | * the array of converted message IDs to send to our service | ||
131 | */ | ||
132 | static int32_t * elements_peer1 = NULL; | ||
133 | |||
134 | /** | ||
135 | * Number of elements | ||
136 | */ | ||
137 | uint16_t element_count_peer1 = 0; | ||
138 | |||
139 | /** | ||
140 | * Input elements for peer2 | ||
141 | */ | ||
142 | char input_elements_peer2[] = "11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11"; | ||
143 | //char input_elements_peer2[] = "11,11,11"; | ||
144 | |||
145 | /** | ||
146 | * Input Mask for peer 2 | ||
147 | */ | ||
148 | char input_mask_peer2[] = "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"; | ||
149 | //char input_mask_peer2[] = "1,1,1"; | ||
150 | |||
151 | /** | ||
152 | * the array of converted message IDs to send to our service | ||
153 | */ | ||
154 | static int32_t * elements_peer2 = NULL; | ||
155 | |||
156 | /** | ||
157 | * the array of converted message IDs to send to our service | ||
158 | */ | ||
159 | static unsigned char * mask_peer2 = NULL; | ||
160 | |||
161 | /** | ||
162 | * Number of elements | ||
163 | */ | ||
164 | uint16_t element_count_peer2 = 0; | ||
165 | |||
166 | /** | ||
167 | * Data context for peer 1 | ||
168 | */ | ||
169 | static struct PeerData peer1; | ||
170 | |||
171 | /** | ||
172 | * Data context for peer 2 | ||
173 | */ | ||
174 | static struct PeerData peer2; | ||
175 | |||
176 | /** | ||
177 | * Various states during test setup | ||
178 | */ | ||
179 | static enum SetupState setup_state; | ||
180 | |||
181 | /** | ||
182 | * Testbed operation handle | ||
183 | */ | ||
184 | static struct GNUNET_TESTBED_Operation *op; | ||
185 | |||
186 | static int ok; | ||
187 | |||
188 | static int responder_ok; | ||
189 | |||
190 | static int requester_ok; | ||
191 | |||
192 | static GNUNET_SCHEDULER_TaskIdentifier abort_task; | ||
193 | /****************************************************************************** | ||
194 | *** Static Functions ***************************** | ||
195 | ******************************************************************************/ | ||
196 | |||
197 | static void | ||
198 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Close sockets and stop testing deamons nicely | ||
203 | */ | ||
204 | static void | ||
205 | do_close (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
206 | { | ||
207 | |||
208 | if (peer1.op != NULL) | ||
209 | do_shutdown (&peer1, NULL); | ||
210 | |||
211 | if (peer2.op != NULL) | ||
212 | do_shutdown (&peer2, NULL); | ||
213 | |||
214 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) | ||
215 | GNUNET_SCHEDULER_cancel (abort_task); | ||
216 | |||
217 | GNUNET_SCHEDULER_shutdown (); /* For shutting down testbed */ | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * Shutdown a peer | ||
222 | * | ||
223 | * @param cls pointer to "struct PeerData" of the peer to be disconnected | ||
224 | * @param tc Task Context | ||
225 | */ | ||
226 | static void | ||
227 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
228 | { | ||
229 | static int shutdown; | ||
230 | shutdown++; | ||
231 | struct PeerData* peer = (struct PeerData*) cls; | ||
232 | |||
233 | if (peer == &peer1) | ||
234 | LOG (GNUNET_ERROR_TYPE_INFO, "Disconnecting Peer1\n\n"); | ||
235 | else if (peer == &peer2) | ||
236 | LOG (GNUNET_ERROR_TYPE_INFO, "Disconnecting Peer2\n\n"); | ||
237 | |||
238 | // peer->op contains handle to the TESTBED_connect_service operation | ||
239 | // calling operation done, leads to call to scalarproduct_da | ||
240 | if (peer->op != NULL) | ||
241 | { | ||
242 | GNUNET_TESTBED_operation_done (peer->op); | ||
243 | peer->op = NULL; | ||
244 | } | ||
245 | |||
246 | if (shutdown >= 2) | ||
247 | GNUNET_SCHEDULER_add_now (&do_close, NULL); | ||
248 | } | ||
249 | |||
250 | |||
251 | /** | ||
252 | * Something went wrong and timed out. Kill everything and set error flag | ||
253 | */ | ||
254 | static void | ||
255 | do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
256 | { | ||
257 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "test: ABORT due to Timeout\n"); | ||
258 | ok = GNUNET_SYSERR; | ||
259 | abort_task = 0; | ||
260 | do_close (cls, tc); | ||
261 | } | ||
262 | |||
263 | |||
264 | /** | ||
265 | * Controller event callback | ||
266 | * | ||
267 | * @param cls NULL | ||
268 | * @param event the controller event | ||
269 | */ | ||
270 | static void | ||
271 | controller_event_cb (void *cls, | ||
272 | const struct GNUNET_TESTBED_EventInformation *event) | ||
273 | { | ||
274 | GNUNET_assert (event->type == GNUNET_TESTBED_ET_OPERATION_FINISHED); | ||
275 | |||
276 | switch (setup_state) | ||
277 | { | ||
278 | case PEER1_SCALARPRODUCT_CONNECT: | ||
279 | case PEER2_SCALARPRODUCT_CONNECT: | ||
280 | GNUNET_assert (NULL == event->details.operation_finished.emsg); | ||
281 | break; | ||
282 | default: | ||
283 | GNUNET_assert (0); | ||
284 | } | ||
285 | } | ||
286 | |||
287 | |||
288 | static void | ||
289 | responder_callback (void *cls, | ||
290 | const struct GNUNET_HashCode * key, | ||
291 | enum GNUNET_SCALARPRODUCT_ResponseStatus status) | ||
292 | { | ||
293 | |||
294 | if (status == GNUNET_SCALARPRODUCT_Status_Failure) | ||
295 | { | ||
296 | LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received status failure\n"); | ||
297 | responder_ok = -1; | ||
298 | } | ||
299 | else if (status == GNUNET_SCALARPRODUCT_Status_InvalidResponse) | ||
300 | { | ||
301 | LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received status invalid response\n"); | ||
302 | responder_ok = -1; | ||
303 | } | ||
304 | else if (GNUNET_SCALARPRODUCT_Status_Timeout == status) | ||
305 | { | ||
306 | LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received timeout occured\n"); | ||
307 | responder_ok = -1; | ||
308 | } | ||
309 | else if (GNUNET_SCALARPRODUCT_Status_ServiceDisconnected == status) | ||
310 | { | ||
311 | LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received service disconnected!!\n"); | ||
312 | responder_ok = -1; | ||
313 | } | ||
314 | else if (GNUNET_SCALARPRODUCT_Status_Success == status) | ||
315 | { | ||
316 | LOG (GNUNET_ERROR_TYPE_INFO, "Responder Client expected response received!\n"); | ||
317 | responder_ok = 1; | ||
318 | } | ||
319 | else | ||
320 | { | ||
321 | LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client status = %d!\n", (int) status); | ||
322 | responder_ok = -1; | ||
323 | } | ||
324 | // TODO : Responder Session Complete. Shutdown Test Cleanly!!! | ||
325 | //do_shutdown(&peer1, NULL); | ||
326 | GNUNET_SCHEDULER_add_now (&do_shutdown, &peer1); | ||
327 | return; | ||
328 | } | ||
329 | |||
330 | |||
331 | static void | ||
332 | requester_callback (void *cls, | ||
333 | const struct GNUNET_HashCode * key, | ||
334 | const struct GNUNET_PeerIdentity * peer, | ||
335 | enum GNUNET_SCALARPRODUCT_ResponseStatus status, | ||
336 | const struct GNUNET_SCALARPRODUCT_client_response *msg) | ||
337 | { | ||
338 | uint32_t product_len; | ||
339 | |||
340 | if (status == GNUNET_SCALARPRODUCT_Status_Failure) | ||
341 | { | ||
342 | LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client received status failure\n"); | ||
343 | requester_ok = -1; | ||
344 | } | ||
345 | else if (status == GNUNET_SCALARPRODUCT_Status_InvalidResponse) | ||
346 | { | ||
347 | LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client received status invalid response\n"); | ||
348 | requester_ok = -1; | ||
349 | } | ||
350 | else if (GNUNET_SCALARPRODUCT_Status_Timeout == status) | ||
351 | { | ||
352 | LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client timeout occured\n"); | ||
353 | requester_ok = -1; | ||
354 | } | ||
355 | else if (GNUNET_SCALARPRODUCT_Status_ServiceDisconnected == status) | ||
356 | { | ||
357 | LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client service disconnected!!\n"); | ||
358 | requester_ok = -1; | ||
359 | } | ||
360 | else if (GNUNET_SCALARPRODUCT_Status_Success != status) | ||
361 | { | ||
362 | LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client Status = %d\n", (int) status); | ||
363 | requester_ok = -1; | ||
364 | } | ||
365 | else if (GNUNET_SCALARPRODUCT_Status_Success == status) | ||
366 | { | ||
367 | LOG (GNUNET_ERROR_TYPE_INFO, "Requester Client expected response received!\n"); | ||
368 | product_len = ntohl(msg->product_length); | ||
369 | |||
370 | if (0 < product_len) | ||
371 | { | ||
372 | gcry_mpi_t result; | ||
373 | gcry_error_t ret = 0; | ||
374 | size_t read = 0; | ||
375 | ret = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, &msg[1], product_len, &read); | ||
376 | |||
377 | if (0 != ret) | ||
378 | { | ||
379 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Could not convert to mpi to value!\n"); | ||
380 | ok = -1; | ||
381 | } | ||
382 | else | ||
383 | { | ||
384 | uint16_t i = 0; | ||
385 | |||
386 | // calculate expected product | ||
387 | gcry_mpi_t expected_result; | ||
388 | gcry_mpi_t v1; | ||
389 | gcry_mpi_t v2; | ||
390 | gcry_mpi_t v1_v2_prod; | ||
391 | |||
392 | expected_result = gcry_mpi_new (0); | ||
393 | |||
394 | for (i = 0; i < element_count_peer1; i++) | ||
395 | { | ||
396 | uint32_t value; | ||
397 | v1_v2_prod = gcry_mpi_new (0); | ||
398 | |||
399 | // long to gcry_mpi_t | ||
400 | value = elements_peer1[i] >= 0 ? elements_peer1[i] : -elements_peer1[i]; | ||
401 | if (elements_peer1[i] < 0) | ||
402 | { | ||
403 | v1 = gcry_mpi_new (0); | ||
404 | gcry_mpi_sub_ui (v1, v1, value); | ||
405 | } | ||
406 | else | ||
407 | v1 = gcry_mpi_set_ui (NULL, value); | ||
408 | |||
409 | // long to gcry_mpi_t | ||
410 | value = elements_peer2[i] >= 0 ? elements_peer2[i] : -elements_peer2[i]; | ||
411 | if (elements_peer2[i] < 0) | ||
412 | { | ||
413 | v2 = gcry_mpi_new (0); | ||
414 | gcry_mpi_sub_ui (v2, v2, value); | ||
415 | } | ||
416 | else | ||
417 | v2 = gcry_mpi_set_ui (NULL, value); | ||
418 | |||
419 | gcry_mpi_mul (v1_v2_prod, v1, v2); | ||
420 | gcry_mpi_add (expected_result, expected_result, v1_v2_prod); | ||
421 | |||
422 | gcry_mpi_release (v1); | ||
423 | gcry_mpi_release (v2); | ||
424 | gcry_mpi_release (v1_v2_prod); | ||
425 | |||
426 | } | ||
427 | |||
428 | // compare the result | ||
429 | if (!gcry_mpi_cmp (expected_result, result)) | ||
430 | { | ||
431 | LOG (GNUNET_ERROR_TYPE_INFO, "Scalar Product matches expected Result!!\n"); | ||
432 | requester_ok = 1; | ||
433 | } | ||
434 | else | ||
435 | { | ||
436 | LOG (GNUNET_ERROR_TYPE_WARNING, "Scalar Product DOES NOT match expected Result!!\n"); | ||
437 | requester_ok = -1; | ||
438 | } | ||
439 | gcry_mpi_release (result); | ||
440 | gcry_mpi_release (expected_result); | ||
441 | } | ||
442 | } | ||
443 | else | ||
444 | { //currently not used, but if we get more info due to MESH we will need this | ||
445 | LOG (GNUNET_ERROR_TYPE_WARNING, "Error during computation of vector product, return code: %d\n", product_len); | ||
446 | requester_ok = -1; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | //do_shutdown(&peer2, NULL); | ||
451 | GNUNET_SCHEDULER_add_now (&do_shutdown, &peer2); | ||
452 | return; | ||
453 | } | ||
454 | |||
455 | /** | ||
456 | * Prepare the message to be sent by peer2 to its scalarproduct service, to | ||
457 | * initiate a request to peer1. | ||
458 | */ | ||
459 | static struct GNUNET_SCALARPRODUCT_QueueEntry * | ||
460 | requester_request () | ||
461 | { | ||
462 | unsigned int i; | ||
463 | int exit_loop; | ||
464 | uint16_t mask_length = 0; | ||
465 | char * begin = input_elements_peer2; | ||
466 | char * end; | ||
467 | int32_t element; | ||
468 | struct GNUNET_SCALARPRODUCT_QueueEntry *qe; | ||
469 | struct GNUNET_HashCode key; | ||
470 | |||
471 | GNUNET_assert (peer2.vh != NULL); | ||
472 | |||
473 | GNUNET_CRYPTO_hash (input_key, strlen (input_key), &key); | ||
474 | |||
475 | /* Read input_elements_peer2, and put in elements_peer2 array */ | ||
476 | exit_loop = 0; | ||
477 | do | ||
478 | { | ||
479 | unsigned int mcount = element_count_peer2; | ||
480 | //ignore empty rows of ,,,,,, | ||
481 | while (*begin == ',') | ||
482 | begin++; | ||
483 | // get the length of the current element and replace , with null | ||
484 | for (end = begin; *end && *end != ','; end++); | ||
485 | |||
486 | if (*end == '\0') | ||
487 | exit_loop = 1; | ||
488 | |||
489 | if (1 != sscanf (begin, "%" SCNd32, &element)) | ||
490 | { | ||
491 | FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin); | ||
492 | ok = -1; | ||
493 | return NULL; | ||
494 | } | ||
495 | |||
496 | GNUNET_array_append (elements_peer2, mcount, element); | ||
497 | element_count_peer2++; | ||
498 | |||
499 | begin = ++end; | ||
500 | } | ||
501 | while (!exit_loop && element_count_peer2 < max_mids); | ||
502 | GNUNET_assert (elements_peer2 != NULL); | ||
503 | GNUNET_assert (element_count_peer2 >= 1); | ||
504 | |||
505 | /* Read input_mask_peer2 and read in mask_peer2 array */ | ||
506 | mask_length = element_count_peer2 / 8 + (element_count_peer2 % 8 ? 1 : 0); | ||
507 | mask_peer2 = GNUNET_malloc ((element_count_peer2 / 8) + 2); | ||
508 | GNUNET_assert (NULL != mask_peer2); | ||
509 | if (NULL != input_mask_peer2) | ||
510 | { | ||
511 | begin = input_mask_peer2; | ||
512 | unsigned short mask_count = 0; | ||
513 | int exit_loop = 0; | ||
514 | |||
515 | do | ||
516 | { | ||
517 | //ignore empty rows of ,,,,,, | ||
518 | while (* begin == ',') | ||
519 | begin++; | ||
520 | // get the length of the current element and replace , with null | ||
521 | // gnunet_ascii-armor uses base32, thus we can use , as separator! | ||
522 | for (end = begin; *end && *end != ','; end++); | ||
523 | |||
524 | if (*end == '\0') | ||
525 | exit_loop = 1; | ||
526 | |||
527 | if (1 != sscanf (begin, "%" SCNd32, &element)) | ||
528 | { | ||
529 | FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin); | ||
530 | ok = -1; | ||
531 | return NULL; | ||
532 | } | ||
533 | |||
534 | GNUNET_assert (mask_count <= element_count_peer2); | ||
535 | |||
536 | if (element) | ||
537 | mask_peer2[mask_count / 8] = mask_peer2[mask_count / 8] | 1 << (mask_count % 8); | ||
538 | |||
539 | mask_count++; | ||
540 | begin = ++end; | ||
541 | } | ||
542 | while (!exit_loop); | ||
543 | // +1 to see if we would have more data, which would indicate malformed/superficial input | ||
544 | GNUNET_assert (mask_count == element_count_peer2); | ||
545 | } | ||
546 | else | ||
547 | { | ||
548 | for (i = 0; i <= mask_length; i++) | ||
549 | mask_peer2[i] = UCHAR_MAX; // all 1's | ||
550 | } | ||
551 | |||
552 | qe = GNUNET_SCALARPRODUCT_request (peer2.vh, | ||
553 | &key, | ||
554 | &peer1.our_id, | ||
555 | element_count_peer2, | ||
556 | mask_length, | ||
557 | elements_peer2, mask_peer2, | ||
558 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10), | ||
559 | &requester_callback, | ||
560 | NULL); | ||
561 | |||
562 | if (qe == NULL) | ||
563 | { | ||
564 | LOG(GNUNET_ERROR_TYPE_ERROR, "Could not send request to scalarproduct service! Exitting!"); | ||
565 | ok = -1; | ||
566 | return NULL; | ||
567 | } | ||
568 | |||
569 | return qe; | ||
570 | } | ||
571 | |||
572 | |||
573 | /** | ||
574 | * Function prepares the message to be sent by peer1 to its scalarproduct service | ||
575 | * to prepare response, and wait for a request session to be initiated by peer1 | ||
576 | */ | ||
577 | static struct GNUNET_SCALARPRODUCT_QueueEntry * | ||
578 | responder_prepare_response () | ||
579 | { | ||
580 | GNUNET_assert (peer1.vh != NULL); | ||
581 | |||
582 | char * begin = input_elements_peer1; | ||
583 | char * end; | ||
584 | int32_t element; | ||
585 | struct GNUNET_SCALARPRODUCT_QueueEntry *qe; | ||
586 | struct GNUNET_HashCode key; | ||
587 | |||
588 | GNUNET_CRYPTO_hash (input_key, strlen (input_key), &key); | ||
589 | |||
590 | /* Read input_elements_peer1, and put in elements_peer1 array */ | ||
591 | int exit_loop = 0; | ||
592 | do | ||
593 | { | ||
594 | unsigned int mcount = element_count_peer1; | ||
595 | //ignore empty rows of ,,,,,, | ||
596 | while (*begin == ',') | ||
597 | begin++; | ||
598 | // get the length of the current element and replace , with null | ||
599 | for (end = begin; *end && *end != ','; end++); | ||
600 | |||
601 | if (*end == '\0') | ||
602 | exit_loop = 1; | ||
603 | |||
604 | if (1 != sscanf (begin, "%" SCNd32, &element)) | ||
605 | { | ||
606 | FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin); | ||
607 | ok = -1; | ||
608 | return NULL; | ||
609 | } | ||
610 | |||
611 | GNUNET_array_append (elements_peer1, mcount, element); | ||
612 | element_count_peer1++; | ||
613 | |||
614 | begin = ++end; | ||
615 | } | ||
616 | while (!exit_loop && element_count_peer1 < max_mids); | ||
617 | GNUNET_assert (elements_peer1 != NULL); | ||
618 | GNUNET_assert (element_count_peer1 >= 1); | ||
619 | |||
620 | qe = GNUNET_SCALARPRODUCT_prepare_response (peer1.vh, | ||
621 | &key, | ||
622 | element_count_peer1, | ||
623 | elements_peer1, | ||
624 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10), | ||
625 | &responder_callback, | ||
626 | NULL); | ||
627 | |||
628 | if (qe == NULL) | ||
629 | { | ||
630 | LOG(GNUNET_ERROR_TYPE_ERROR, "Could not send request to scalarproduct service! Exitting!"); | ||
631 | ok = -1; | ||
632 | return NULL; | ||
633 | } | ||
634 | |||
635 | return qe; | ||
636 | } | ||
637 | |||
638 | |||
639 | /** | ||
640 | * Scheduler task to initiate requester client | ||
641 | * | ||
642 | * @param cls void* to struct PeerData | ||
643 | * @param tc Task Context | ||
644 | */ | ||
645 | static void | ||
646 | request_task(void *cls, | ||
647 | const struct GNUNET_SCHEDULER_TaskContext | ||
648 | * tc) | ||
649 | { | ||
650 | requester_request(); | ||
651 | return; | ||
652 | } | ||
653 | |||
654 | /** | ||
655 | * Scheduler task to initiate responder client | ||
656 | * | ||
657 | * @param cls void* to struct PeerData | ||
658 | * @param tc Task Context | ||
659 | */ | ||
660 | static void | ||
661 | prepare_response_task(void *cls, | ||
662 | const struct GNUNET_SCHEDULER_TaskContext | ||
663 | * tc) | ||
664 | { | ||
665 | responder_prepare_response(); | ||
666 | return; | ||
667 | } | ||
668 | |||
669 | |||
670 | /** | ||
671 | * Adapter function called to destroy a connection to | ||
672 | * a service. This function is called when GNUNET_TESTBED_operation_done is | ||
673 | * called for peer->op, which holds the handle for GNUNET_TESTBED_service_connect | ||
674 | * operation. | ||
675 | * | ||
676 | * @param cls closure | ||
677 | * @param op_result service handle returned from the connect adapter | ||
678 | */ | ||
679 | static void | ||
680 | scalarproduct_da (void *cls, void *op_result) | ||
681 | { | ||
682 | struct PeerData* peer = (struct PeerData*) cls; | ||
683 | |||
684 | GNUNET_SCALARPRODUCT_cancel (peer->vh); | ||
685 | return; | ||
686 | } | ||
687 | |||
688 | |||
689 | /** | ||
690 | * Adapter function called to establish a connection to | ||
691 | * a service. This function is called to by GNUNET_TESTBED_service_connect. | ||
692 | * | ||
693 | * @param cls closure | ||
694 | * @param cfg configuration of the peer to connect to; will be available until | ||
695 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
696 | * from GNUNET_TESTBED_service_connect() | ||
697 | * @return service handle to return in 'op_result', NULL on error | ||
698 | */ | ||
699 | static void * | ||
700 | scalarproduct_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
701 | { | ||
702 | struct PeerData *p = cls; | ||
703 | |||
704 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%s') started\n", (&peer1 == p) ? 1 : 2, | ||
705 | GNUNET_i2s (&p->our_id)); | ||
706 | |||
707 | switch (setup_state) | ||
708 | { | ||
709 | case PEER1_SCALARPRODUCT_CONNECT: | ||
710 | /* Connect peer 2 to scalarproduct service */ | ||
711 | { | ||
712 | peer2.op = GNUNET_TESTBED_service_connect (&peer2, peer2.peer, "scalarproduct", | ||
713 | NULL, NULL, scalarproduct_ca, | ||
714 | scalarproduct_da, &peer2); | ||
715 | setup_state = PEER2_SCALARPRODUCT_CONNECT; | ||
716 | } | ||
717 | |||
718 | /* Actually connect peer 1 to scalarproduct service */ | ||
719 | peer1.vh = GNUNET_SCALARPRODUCT_connect (cfg); | ||
720 | return peer1.vh; | ||
721 | |||
722 | case PEER2_SCALARPRODUCT_CONNECT: | ||
723 | /* Actually connect peer 2 to scalarproduct service */ | ||
724 | peer2.vh = GNUNET_SCALARPRODUCT_connect (cfg); | ||
725 | |||
726 | /* Schedule tasks to initiate request from peer2 and prepare_response from peer1 */ | ||
727 | if(peer1.vh != NULL && peer2.vh != NULL) | ||
728 | { | ||
729 | GNUNET_SCHEDULER_add_now(&prepare_response_task, &peer1); | ||
730 | GNUNET_SCHEDULER_add_now(&request_task, &peer2); | ||
731 | } | ||
732 | |||
733 | return peer2.vh; | ||
734 | default: | ||
735 | GNUNET_assert (0); | ||
736 | } | ||
737 | } | ||
738 | |||
739 | |||
740 | /** | ||
741 | * Callback to be called when the requested peer information is available | ||
742 | * | ||
743 | * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information() | ||
744 | * @param op the operation this callback corresponds to | ||
745 | * @param pinfo the result; will be NULL if the operation has failed | ||
746 | * @param emsg error message if the operation has failed; will be NULL if the | ||
747 | * operation is successfull | ||
748 | */ | ||
749 | static void | ||
750 | peerinfo_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op_, | ||
751 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | ||
752 | const char *emsg) | ||
753 | { | ||
754 | GNUNET_assert (NULL == emsg); | ||
755 | GNUNET_assert (op == op_); | ||
756 | switch (setup_state) | ||
757 | { | ||
758 | case PEER1_GET_IDENTITY: | ||
759 | { | ||
760 | memcpy (&peer1.our_id, pinfo->result.id, | ||
761 | sizeof (struct GNUNET_PeerIdentity)); | ||
762 | GNUNET_TESTBED_operation_done (op); | ||
763 | |||
764 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 1 id: %s\n", GNUNET_i2s_full | ||
765 | (&peer1.our_id)); | ||
766 | |||
767 | /* Request for peer id of peer 2*/ | ||
768 | op = GNUNET_TESTBED_peer_get_information (peer2.peer, | ||
769 | GNUNET_TESTBED_PIT_IDENTITY, | ||
770 | &peerinfo_cb, NULL); | ||
771 | setup_state = PEER2_GET_IDENTITY; | ||
772 | } | ||
773 | break; | ||
774 | case PEER2_GET_IDENTITY: | ||
775 | { | ||
776 | memcpy (&peer2.our_id, pinfo->result.id, | ||
777 | sizeof (struct GNUNET_PeerIdentity)); | ||
778 | GNUNET_TESTBED_operation_done (op); | ||
779 | |||
780 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 2 id: %s\n", GNUNET_i2s_full | ||
781 | (&peer2.our_id)); | ||
782 | |||
783 | /* Connect peer 1 to scalarproduct service */ | ||
784 | peer1.op = GNUNET_TESTBED_service_connect (&peer1, peer1.peer, "scalarproduct", | ||
785 | NULL, NULL, scalarproduct_ca, | ||
786 | scalarproduct_da, &peer1); | ||
787 | setup_state = PEER1_SCALARPRODUCT_CONNECT; | ||
788 | } | ||
789 | break; | ||
790 | default: | ||
791 | GNUNET_assert (0); | ||
792 | } | ||
793 | } | ||
794 | |||
795 | |||
796 | /** | ||
797 | * Signature of a main function for a testcase. | ||
798 | * | ||
799 | * @param cls closure | ||
800 | * @param num_peers number of peers in 'peers' | ||
801 | * @param peers handle to peers run in the testbed | ||
802 | */ | ||
803 | static void | ||
804 | test_master (void *cls, unsigned int num_peers, | ||
805 | struct GNUNET_TESTBED_Peer **peers) | ||
806 | { | ||
807 | GNUNET_assert (NULL != peers); | ||
808 | GNUNET_assert (NULL != peers[0]); | ||
809 | GNUNET_assert (NULL != peers[1]); | ||
810 | peer1.peer = peers[0]; | ||
811 | peer2.peer = peers[1]; | ||
812 | /* Get the peer identity and configuration of peer 1 */ | ||
813 | op = GNUNET_TESTBED_peer_get_information (peer1.peer, | ||
814 | GNUNET_TESTBED_PIT_IDENTITY, | ||
815 | &peerinfo_cb, NULL); | ||
816 | setup_state = PEER1_GET_IDENTITY; | ||
817 | |||
818 | /* Abort task for stopping test on timeout */ | ||
819 | abort_task = | ||
820 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | ||
821 | (GNUNET_TIME_UNIT_SECONDS, 20), &do_abort, | ||
822 | NULL); | ||
823 | } | ||
824 | |||
825 | |||
826 | /** | ||
827 | * Main function | ||
828 | */ | ||
829 | int | ||
830 | main (int argc, char **argv) | ||
831 | { | ||
832 | uint64_t event_mask; | ||
833 | |||
834 | ok = GNUNET_NO; | ||
835 | event_mask = 0; | ||
836 | event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); | ||
837 | max_mids = (GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_MessageHeader)) | ||
838 | / sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1; | ||
839 | |||
840 | (void) GNUNET_TESTBED_test_run ("test_scalarproduct_api", | ||
841 | "test_scalarproduct_api_data.conf", | ||
842 | NUM_PEERS, event_mask, &controller_event_cb, | ||
843 | NULL, | ||
844 | &test_master, NULL); | ||
845 | |||
846 | if (GNUNET_SYSERR == ok) | ||
847 | { | ||
848 | LOG (GNUNET_ERROR_TYPE_ERROR, "Test failing due to some error before calling API for request or prepare_response\n"); | ||
849 | return 1; | ||
850 | } | ||
851 | else if (GNUNET_SYSERR == responder_ok) | ||
852 | { | ||
853 | LOG (GNUNET_ERROR_TYPE_ERROR, "Test failing due to some error in responding_client\n"); | ||
854 | return 1; | ||
855 | } | ||
856 | else if (GNUNET_SYSERR == requester_ok) | ||
857 | { | ||
858 | LOG (GNUNET_ERROR_TYPE_ERROR, "Test failing due to some error in requesting client\n"); | ||
859 | return 1; | ||
860 | } | ||
861 | else | ||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | |||
diff --git a/src/scalarproduct/test_scalarproduct_negative.sh b/src/scalarproduct/test_scalarproduct_negative.sh new file mode 100755 index 000000000..27fd345cc --- /dev/null +++ b/src/scalarproduct/test_scalarproduct_negative.sh | |||
@@ -0,0 +1,49 @@ | |||
1 | #!/bin/bash | ||
2 | # compute a simple scalar product | ||
3 | # payload for this test: | ||
4 | INPUTALICE="-k CCC -e -3,-3,1" | ||
5 | INPUTBOB="-k CCC -e 1000,100,24" | ||
6 | |||
7 | # necessary to make the testing prefix deterministic, so we can access the config files | ||
8 | PREFIX=/tmp/test-scalarproduct`date +%H%M%S` | ||
9 | |||
10 | # where can we find the peers config files? | ||
11 | CFGALICE="-c $PREFIX/0/config" | ||
12 | CFGBOB="-c $PREFIX/1/config" | ||
13 | |||
14 | # launch two peers in line topology non-interactively | ||
15 | # | ||
16 | # interactive mode would terminate the test immediately | ||
17 | # because the rest of the script is already in stdin, | ||
18 | # thus redirecting stdin does not suffice) | ||
19 | GNUNET_LOG='scalarproduct;;;;DEBUG' GNUNET_TESTING_PREFIX=$PREFIX ../testbed/gnunet-testbed-profiler -n -c test_scalarproduct.conf -p 2 2>service.log & | ||
20 | PID=$! | ||
21 | sleep 5 | ||
22 | |||
23 | # get bob's peer ID, necessary for alice | ||
24 | PEERIDBOB=`gnunet-peerinfo -qs $CFGBOB` | ||
25 | |||
26 | GNUNET_LOG='scalarproduct;;;;DEBUG' gnunet-scalarproduct $CFGBOB $INPUTBOB 2>bob.log & | ||
27 | RESULT=`GNUNET_LOG='scalarproduct;;;;DEBUG' gnunet-scalarproduct $CFGALICE $INPUTALICE -p $PEERIDBOB 2>alice.log` | ||
28 | |||
29 | cat alice.log bob.log service.log >> test_scalarproduct.log | ||
30 | rm -f alice.log bob.log service.log | ||
31 | ISSUES=$((`grep scalarproduct test_scalarproduct.log | grep -c ERROR` + `grep scalarproduct test_scalarproduct.log | grep -c WARNING`)) | ||
32 | |||
33 | # terminate the testbed | ||
34 | kill $PID | ||
35 | |||
36 | EXPECTED="-0CCC" | ||
37 | if [ "$ISSUES" -eq "0" ] | ||
38 | then | ||
39 | if [ "$RESULT" == "$EXPECTED" ] | ||
40 | then | ||
41 | echo "OK" | ||
42 | rm -f test_scalarproduct.log | ||
43 | exit 0 | ||
44 | fi | ||
45 | else | ||
46 | echo "Result $RESULT NOTOK, see $PWD/test_scalarproduct.log for details" | ||
47 | exit 1 | ||
48 | fi | ||
49 | |||
diff --git a/src/scalarproduct/test_scalarproduct_negativezero.sh b/src/scalarproduct/test_scalarproduct_negativezero.sh new file mode 100755 index 000000000..5035bdffd --- /dev/null +++ b/src/scalarproduct/test_scalarproduct_negativezero.sh | |||
@@ -0,0 +1,49 @@ | |||
1 | #!/bin/bash | ||
2 | # compute a simple scalar product | ||
3 | # payload for this test: | ||
4 | INPUTALICE="-k CCC -e -1,1,-1" | ||
5 | INPUTBOB="-k CCC -e 1,1,0" | ||
6 | |||
7 | # necessary to make the testing prefix deterministic, so we can access the config files | ||
8 | PREFIX=/tmp/test-scalarproduct`date +%H%M%S` | ||
9 | |||
10 | # where can we find the peers config files? | ||
11 | CFGALICE="-c $PREFIX/0/config" | ||
12 | CFGBOB="-c $PREFIX/1/config" | ||
13 | |||
14 | # launch two peers in line topology non-interactively | ||
15 | # | ||
16 | # interactive mode would terminate the test immediately | ||
17 | # because the rest of the script is already in stdin, | ||
18 | # thus redirecting stdin does not suffice) | ||
19 | GNUNET_LOG='scalarproduct;;;;DEBUG' GNUNET_TESTING_PREFIX=$PREFIX ../testbed/gnunet-testbed-profiler -n -c test_scalarproduct.conf -p 2 2>service.log & | ||
20 | PID=$! | ||
21 | sleep 5 | ||
22 | |||
23 | # get bob's peer ID, necessary for alice | ||
24 | PEERIDBOB=`gnunet-peerinfo -qs $CFGBOB` | ||
25 | |||
26 | GNUNET_LOG='scalarproduct;;;;DEBUG' gnunet-scalarproduct $CFGBOB $INPUTBOB 2>bob.log & | ||
27 | RESULT=`GNUNET_LOG='scalarproduct;;;;DEBUG' gnunet-scalarproduct $CFGALICE $INPUTALICE -p $PEERIDBOB 2>alice.log` | ||
28 | |||
29 | cat alice.log bob.log service.log >> test_scalarproduct.log | ||
30 | rm -f alice.log bob.log service.log | ||
31 | ISSUES=$((`grep scalarproduct test_scalarproduct.log | grep -c ERROR` + `grep scalarproduct test_scalarproduct.log | grep -c WARNING`)) | ||
32 | |||
33 | # terminate the testbed | ||
34 | kill $PID | ||
35 | |||
36 | EXPECTED="00" | ||
37 | if [ "$ISSUES" -eq "0" ] | ||
38 | then | ||
39 | if [ "$RESULT" == "$EXPECTED" ] | ||
40 | then | ||
41 | echo "OK" | ||
42 | rm -f test_scalarproduct.log | ||
43 | exit 0 | ||
44 | fi | ||
45 | else | ||
46 | echo "Result $RESULT NOTOK, see $PWD/test_scalarproduct.log for details" | ||
47 | exit 1 | ||
48 | fi | ||
49 | |||