aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-02-27 13:43:00 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-02-27 13:43:00 +0000
commit43a56296dfb61c42bf8789ffae3d5b7a94d12304 (patch)
treea23ed86d6dc16f9c19dc2bda1673accd26008a65
parent9019f5522b5d1dc7605630c050ce8ff324e2c5a5 (diff)
downloadgnunet-43a56296dfb61c42bf8789ffae3d5b7a94d12304.tar.gz
gnunet-43a56296dfb61c42bf8789ffae3d5b7a94d12304.zip
new test
-rw-r--r--src/ats/Makefile.am14
-rw-r--r--src/ats/gnunet-service-ats_addresses_mlp.c500
-rw-r--r--src/ats/test_ats_mlp_update.c255
3 files changed, 485 insertions, 284 deletions
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am
index e93cc11c1..6aca15483 100644
--- a/src/ats/Makefile.am
+++ b/src/ats/Makefile.am
@@ -18,7 +18,8 @@ endif
18if HAVE_LIBGLPK 18if HAVE_LIBGLPK
19 GN_LIBGLPK = -lglpk 19 GN_LIBGLPK = -lglpk
20 GN_MLP_SRC = gnunet-service-ats_addresses_mlp.c gnunet-service-ats_addresses_mlp.h 20 GN_MLP_SRC = gnunet-service-ats_addresses_mlp.c gnunet-service-ats_addresses_mlp.h
21 GN_MLP_TEST = test_ats_mlp 21 GN_MLP_TEST = test_ats_mlp
22 GN_MLP_TEST_UPDATE = test_ats_mlp_update
22 GN_MLP_TEST_AVG = test_ats_mlp_averaging 23 GN_MLP_TEST_AVG = test_ats_mlp_averaging
23 GN_MLP_PERF = perf_ats_mlp 24 GN_MLP_PERF = perf_ats_mlp
24endif 25endif
@@ -74,7 +75,7 @@ check_PROGRAMS = \
74 test_ats_simplistic_change_preference \ 75 test_ats_simplistic_change_preference \
75 test_ats_simplistic_pref_aging \ 76 test_ats_simplistic_pref_aging \
76 test_ats_api_performance \ 77 test_ats_api_performance \
77 $(GN_MLP_TEST) $(GN_MLP_PERF) 78 $(GN_MLP_TEST) $(GN_MLP_PERF) $(GN_MLP_TEST_UPDATE)
78# $(GN_MLP_TEST_AVG) 79# $(GN_MLP_TEST_AVG)
79# test_ats_api_scheduling_get_type 80# test_ats_api_scheduling_get_type
80# test_ats_api_bandwidth_consumption 81# test_ats_api_bandwidth_consumption
@@ -201,6 +202,15 @@ test_ats_mlp_LDADD = \
201 $(top_builddir)/src/util/libgnunetutil.la \ 202 $(top_builddir)/src/util/libgnunetutil.la \
202 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 203 $(top_builddir)/src/statistics/libgnunetstatistics.la \
203 $(top_builddir)/src/ats/libgnunetats.la 204 $(top_builddir)/src/ats/libgnunetats.la
205
206test_ats_mlp_update_SOURCES = \
207 $(GN_MLP_SRC) test_ats_mlp_update.c test_ats_api_common.c
208test_ats_mlp_update_LDADD = \
209 $(GN_LIBGLPK) \
210 $(top_builddir)/src/util/libgnunetutil.la \
211 $(top_builddir)/src/statistics/libgnunetstatistics.la \
212 $(top_builddir)/src/ats/libgnunetats.la
213
204 214
205perf_ats_mlp_SOURCES = \ 215perf_ats_mlp_SOURCES = \
206 $(GN_MLP_SRC) perf_ats_mlp.c test_ats_api_common.c 216 $(GN_MLP_SRC) perf_ats_mlp.c test_ats_api_common.c
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c
index 0a1bf7002..f047ab48f 100644
--- a/src/ats/gnunet-service-ats_addresses_mlp.c
+++ b/src/ats/gnunet-service-ats_addresses_mlp.c
@@ -348,200 +348,6 @@ mlp_solve_to_string (int retcode)
348} 348}
349 349
350 350
351#if 0
352
353#if 0
354/**
355 * Find the required ATS information for an address
356 *
357 * @param addr the address
358 * @param ats_index the desired ATS index
359 *
360 * @return the index on success, otherwise GNUNET_SYSERR
361 */
362static int
363mlp_lookup_ats (struct ATS_Address *addr, int ats_index)
364{
365 struct GNUNET_ATS_Information * ats = addr->ats;
366 int c = 0;
367 int found = GNUNET_NO;
368 for (c = 0; c < addr->ats_count; c++)
369 {
370 if (ats[c].type == ats_index)
371 {
372 found = GNUNET_YES;
373 break;
374 }
375 }
376 if (found == GNUNET_YES)
377 return c;
378 else
379 return GNUNET_SYSERR;
380}
381#endif
382
383static void
384update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address)
385{
386 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality metrics for peer `%s'\n",
387 GNUNET_i2s (&address->peer));
388
389 GNUNET_assert (NULL != address);
390 GNUNET_assert (NULL != address->solver_information);
391// GNUNET_assert (NULL != address->ats);
392
393 struct MLP_information *mlpi = address->solver_information;
394 //struct GNUNET_ATS_Information *ats = address->ats;
395 GNUNET_assert (mlpi != NULL);
396
397 int c;
398 for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
399 {
400
401 /* FIXME int index = mlp_lookup_ats(address, mlp->q[c]); */
402 int index = GNUNET_SYSERR;
403
404 if (index == GNUNET_SYSERR)
405 continue;
406 /* FIXME
407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' value `%s': %f\n",
408 GNUNET_i2s (&address->peer),
409 mlp_ats_to_string(mlp->q[c]),
410 (double) ats[index].value);
411
412 int i = mlpi->q_avg_i[c];*/
413 double * qp = mlpi->q[c];
414 /* FIXME
415 qp[i] = (double) ats[index].value;
416 */
417
418 int t;
419 for (t = 0; t < MLP_AVERAGING_QUEUE_LENGTH; t++)
420 {
421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' queue[%u]: %f\n",
422 GNUNET_i2s (&address->peer),
423 mlp_ats_to_string(mlp->q[c]),
424 t,
425 qp[t]);
426 }
427
428 if (mlpi->q_avg_i[c] + 1 < (MLP_AVERAGING_QUEUE_LENGTH))
429 mlpi->q_avg_i[c] ++;
430 else
431 mlpi->q_avg_i[c] = 0;
432
433
434 int c2;
435 int c3;
436 double avg = 0.0;
437 switch (mlp->q[c])
438 {
439 case GNUNET_ATS_QUALITY_NET_DELAY:
440 c3 = 0;
441 for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
442 {
443 if (mlpi->q[c][c2] != -1)
444 {
445 double * t2 = mlpi->q[c] ;
446 avg += t2[c2];
447 c3 ++;
448 }
449 }
450 if ((c3 > 0) && (avg > 0))
451 /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
452 mlpi->q_averaged[c] = (double) c3 / avg;
453 else
454 mlpi->q_averaged[c] = 0.0;
455
456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n",
457 GNUNET_i2s (&address->peer),
458 mlp_ats_to_string(mlp->q[c]),
459 avg,
460 avg / (double) c3,
461 mlpi->q_averaged[c]);
462
463 break;
464 case GNUNET_ATS_QUALITY_NET_DISTANCE:
465 c3 = 0;
466 for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
467 {
468 if (mlpi->q[c][c2] != -1)
469 {
470 double * t2 = mlpi->q[c] ;
471 avg += t2[c2];
472 c3 ++;
473 }
474 }
475 if ((c3 > 0) && (avg > 0))
476 /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
477 mlpi->q_averaged[c] = (double) c3 / avg;
478 else
479 mlpi->q_averaged[c] = 0.0;
480
481 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n",
482 GNUNET_i2s (&address->peer),
483 mlp_ats_to_string(mlp->q[c]),
484 avg,
485 avg / (double) c3,
486 mlpi->q_averaged[c]);
487
488 break;
489 default:
490 break;
491 }
492
493 if ((mlpi->c_b != 0) && (mlpi->r_q[c] != 0))
494 {
495
496 /* Get current number of columns */
497 int found = GNUNET_NO;
498 int cols = glp_get_num_cols(mlp->prob);
499 int *ind = GNUNET_malloc (cols * sizeof (int) + 1);
500 double *val = GNUNET_malloc (cols * sizeof (double) + 1);
501
502 /* Get the matrix row of quality */
503 int length = glp_get_mat_row(mlp->prob, mlp->r_q[c], ind, val);
504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "cols %i, length %i c_b %i\n", cols, length, mlpi->c_b);
505 int c4;
506 /* Get the index if matrix row of quality */
507 for (c4 = 1; c4 <= length; c4++ )
508 {
509 if (mlpi->c_b == ind[c4])
510 {
511 /* Update the value */
512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality `%s' column `%s' row `%s' : %f -> %f\n",
513 mlp_ats_to_string(mlp->q[c]),
514 glp_get_col_name (mlp->prob, ind[c4]),
515 glp_get_row_name (mlp->prob, mlp->r_q[c]),
516 val[c4],
517 mlpi->q_averaged[c]);
518 val[c4] = mlpi->q_averaged[c];
519 found = GNUNET_YES;
520 break;
521 }
522 }
523
524 if (found == GNUNET_NO)
525 {
526
527 ind[length+1] = mlpi->c_b;
528 val[length+1] = mlpi->q_averaged[c];
529 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%i ind[%i] val[%i]: %i %f\n", length+1, length+1, length+1, mlpi->c_b, mlpi->q_averaged[c]);
530 glp_set_mat_row (mlp->prob, mlpi->r_q[c], length+1, ind, val);
531 }
532 else
533 {
534 /* Get the index if matrix row of quality */
535 glp_set_mat_row (mlp->prob, mlpi->r_q[c], length, ind, val);
536 }
537
538 GNUNET_free (ind);
539 GNUNET_free (val);
540 }
541 }
542}
543
544#endif
545 351
546 352
547struct CountContext 353struct CountContext
@@ -1220,6 +1026,217 @@ GAS_mlp_address_add (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addres
1220 GAS_mlp_solve_problem (solver, addresses); 1026 GAS_mlp_solve_problem (solver, addresses);
1221} 1027}
1222 1028
1029
1030static void
1031mlp_update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address,
1032 const struct GNUNET_ATS_Information *ats, uint32_t ats_count)
1033{
1034 struct MLP_information *mlpi = address->solver_information;
1035 unsigned int c;
1036 unsigned int c2;
1037 unsigned int type_index;
1038 unsigned int avg_index;
1039 uint32_t type;
1040 uint32_t value;
1041
1042 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality metrics for peer `%s'\n",
1043 GNUNET_i2s (&address->peer));
1044
1045 GNUNET_assert (NULL != address);
1046 GNUNET_assert (NULL != address->solver_information);
1047 GNUNET_assert (NULL != ats);
1048
1049 for (c = 0; c < ats_count; c++)
1050 {
1051 type = ntohl (ats[c].type);
1052 value = ntohl (ats[c].value);
1053
1054 /* Find index for this ATS type */
1055 for (c2 = 0; c < ats_count; c++)
1056 {
1057 if (type == mlp->pv.q[c2])
1058 {
1059 type_index = c2;
1060 break;
1061 }
1062 }
1063 if (type_index > ats_count)
1064 continue; /* quality index not found */
1065
1066 /* Get average queue index */
1067 avg_index = mlpi->q_avg_i[type_index];
1068
1069 /* Update averaging queue */
1070 mlpi->q[type_index][avg_index] = value;
1071
1072 /* Update averaging index */
1073 if (mlpi->q_avg_i[c] + 1 < (MLP_AVERAGING_QUEUE_LENGTH))
1074 mlpi->q_avg_i[c] ++;
1075 else
1076 mlpi->q_avg_i[c] = 0;
1077
1078 /* Update average */
1079
1080 /* Update problem matrix */
1081
1082 }
1083
1084
1085#if 0
1086// GNUNET_assert (NULL != address->ats);
1087
1088
1089 //struct GNUNET_ATS_Information *ats = address->ats;
1090 GNUNET_assert (mlpi != NULL);
1091
1092 int c;
1093 for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
1094 {
1095
1096 /* FIXME int index = mlp_lookup_ats(address, mlp->q[c]); */
1097 int type_index = GNUNET_SYSERR;
1098
1099 if (type_index == GNUNET_SYSERR)
1100 continue;
1101 /* FIXME
1102 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' value `%s': %f\n",
1103 GNUNET_i2s (&address->peer),
1104 mlp_ats_to_string(mlp->q[c]),
1105 (double) ats[index].value);
1106
1107 int i = mlpi->q_avg_i[c];*/
1108 double * qp = mlpi->q[c];
1109 /* FIXME
1110 qp[i] = (double) ats[index].value;
1111 */
1112
1113 int t;
1114 for (t = 0; t < MLP_AVERAGING_QUEUE_LENGTH; t++)
1115 {
1116 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' queue[%u]: %f\n",
1117 GNUNET_i2s (&address->peer),
1118 mlp_ats_to_string(mlp->q[c]),
1119 t,
1120 qp[t]);
1121 }
1122
1123 if (mlpi->q_avg_i[c] + 1 < (MLP_AVERAGING_QUEUE_LENGTH))
1124 mlpi->q_avg_i[c] ++;
1125 else
1126 mlpi->q_avg_i[c] = 0;
1127
1128
1129 int c2;
1130 int c3;
1131 double avg = 0.0;
1132 switch (mlp->q[c])
1133 {
1134 case GNUNET_ATS_QUALITY_NET_DELAY:
1135 c3 = 0;
1136 for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
1137 {
1138 if (mlpi->q[c][c2] != -1)
1139 {
1140 double * t2 = mlpi->q[c] ;
1141 avg += t2[c2];
1142 c3 ++;
1143 }
1144 }
1145 if ((c3 > 0) && (avg > 0))
1146 /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
1147 mlpi->q_averaged[c] = (double) c3 / avg;
1148 else
1149 mlpi->q_averaged[c] = 0.0;
1150
1151 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n",
1152 GNUNET_i2s (&address->peer),
1153 mlp_ats_to_string(mlp->q[c]),
1154 avg,
1155 avg / (double) c3,
1156 mlpi->q_averaged[c]);
1157
1158 break;
1159 case GNUNET_ATS_QUALITY_NET_DISTANCE:
1160 c3 = 0;
1161 for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
1162 {
1163 if (mlpi->q[c][c2] != -1)
1164 {
1165 double * t2 = mlpi->q[c] ;
1166 avg += t2[c2];
1167 c3 ++;
1168 }
1169 }
1170 if ((c3 > 0) && (avg > 0))
1171 /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
1172 mlpi->q_averaged[c] = (double) c3 / avg;
1173 else
1174 mlpi->q_averaged[c] = 0.0;
1175
1176 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n",
1177 GNUNET_i2s (&address->peer),
1178 mlp_ats_to_string(mlp->q[c]),
1179 avg,
1180 avg / (double) c3,
1181 mlpi->q_averaged[c]);
1182
1183 break;
1184 default:
1185 break;
1186 }
1187
1188 if ((mlpi->c_b != 0) && (mlpi->r_q[c] != 0))
1189 {
1190
1191 /* Get current number of columns */
1192 int found = GNUNET_NO;
1193 int cols = glp_get_num_cols(mlp->prob);
1194 int *ind = GNUNET_malloc (cols * sizeof (int) + 1);
1195 double *val = GNUNET_malloc (cols * sizeof (double) + 1);
1196
1197 /* Get the matrix row of quality */
1198 int length = glp_get_mat_row(mlp->prob, mlp->r_q[c], ind, val);
1199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "cols %i, length %i c_b %i\n", cols, length, mlpi->c_b);
1200 int c4;
1201 /* Get the index if matrix row of quality */
1202 for (c4 = 1; c4 <= length; c4++ )
1203 {
1204 if (mlpi->c_b == ind[c4])
1205 {
1206 /* Update the value */
1207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality `%s' column `%s' row `%s' : %f -> %f\n",
1208 mlp_ats_to_string(mlp->q[c]),
1209 glp_get_col_name (mlp->prob, ind[c4]),
1210 glp_get_row_name (mlp->prob, mlp->r_q[c]),
1211 val[c4],
1212 mlpi->q_averaged[c]);
1213 val[c4] = mlpi->q_averaged[c];
1214 found = GNUNET_YES;
1215 break;
1216 }
1217 }
1218
1219 if (found == GNUNET_NO)
1220 {
1221
1222 ind[length+1] = mlpi->c_b;
1223 val[length+1] = mlpi->q_averaged[c];
1224 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%i ind[%i] val[%i]: %i %f\n", length+1, length+1, length+1, mlpi->c_b, mlpi->q_averaged[c]);
1225 glp_set_mat_row (mlp->prob, mlpi->r_q[c], length+1, ind, val);
1226 }
1227 else
1228 {
1229 /* Get the index if matrix row of quality */
1230 glp_set_mat_row (mlp->prob, mlpi->r_q[c], length, ind, val);
1231 }
1232
1233 GNUNET_free (ind);
1234 GNUNET_free (val);
1235 }
1236 }
1237#endif
1238}
1239
1223/** 1240/**
1224 * Updates a single address in the MLP problem 1241 * Updates a single address in the MLP problem
1225 * 1242 *
@@ -1248,13 +1265,19 @@ GAS_mlp_address_update (void *solver,
1248{ 1265{
1249 struct ATS_Peer *p; 1266 struct ATS_Peer *p;
1250 struct GAS_MLP_Handle *mlp = solver; 1267 struct GAS_MLP_Handle *mlp = solver;
1268 struct MLP_information *mlpi = address->solver_information;
1251 1269
1252 GNUNET_assert (NULL != solver); 1270 GNUNET_assert (NULL != solver);
1253 GNUNET_assert (NULL != addresses); 1271 GNUNET_assert (NULL != addresses);
1254 GNUNET_assert (NULL != address); 1272 GNUNET_assert (NULL != address);
1255 GNUNET_assert ((NULL != atsi) || (0 == atsi_count)); 1273 GNUNET_assert ((NULL != atsi) || (0 == atsi_count));
1256 1274
1257 /* TODO Update address here */ 1275 if (NULL == mlpi)
1276 {
1277 LOG (GNUNET_ERROR_TYPE_ERROR, _("Updating address for peer `%s' not added before\n"), GNUNET_i2s(&address->peer));
1278 return;
1279 }
1280 mlp_update_quality (mlp, address, atsi, atsi_count);
1258 1281
1259 /* Is this peer included in the problem? */ 1282 /* Is this peer included in the problem? */
1260 if (NULL == (p = GNUNET_CONTAINER_multihashmap_get (mlp->peers, &address->peer.hashPubKey))) 1283 if (NULL == (p = GNUNET_CONTAINER_multihashmap_get (mlp->peers, &address->peer.hashPubKey)))
@@ -1269,93 +1292,6 @@ GAS_mlp_address_update (void *solver,
1269 if (GNUNET_YES == mlp->mlp_auto_solve) 1292 if (GNUNET_YES == mlp->mlp_auto_solve)
1270 GAS_mlp_solve_problem (solver, addresses); 1293 GAS_mlp_solve_problem (solver, addresses);
1271 return; 1294 return;
1272
1273#if 0
1274 GNUNET_STATISTICS_update (mlp->stats, "# MLP address updates", 1, GNUNET_NO);
1275
1276 /* We add a new address */
1277 if (address->solver_information == NULL)
1278 new = GNUNET_YES;
1279 else
1280 new = GNUNET_NO;
1281
1282 /* Do the update */
1283 if (new == GNUNET_YES)
1284 {
1285 mlpi = GNUNET_malloc (sizeof (struct MLP_information));
1286
1287 int c;
1288 for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
1289 {
1290 int c2;
1291 mlpi->r_q[c] = 0;
1292 for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
1293 mlpi->q[c][c2] = -1.0; /* -1.0: invalid value */
1294 mlpi->q_avg_i[c] = 0;
1295 mlpi->q_averaged[c] = 0.0;
1296 }
1297
1298 address->solver_information = mlpi;
1299 mlp->num_addresses ++;
1300 GNUNET_STATISTICS_update (mlp->stats, "# addresses in MLP", 1, GNUNET_NO);
1301
1302 /* Check for and add peer */
1303 struct ATS_Peer *peer = mlp_find_peer (mlp, &address->peer);
1304 if (peer == NULL)
1305 {
1306
1307 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding new peer `%s'\n",
1308 GNUNET_i2s (&address->peer));
1309
1310 peer = GNUNET_malloc (sizeof (struct ATS_Peer));
1311 peer->head = NULL;
1312 peer->tail = NULL;
1313
1314 int c;
1315 for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
1316 {
1317 peer->f_q[c] = 1.0;
1318 }
1319 peer->f = 1.0;
1320
1321 memcpy (&peer->id, &address->peer, sizeof (struct GNUNET_PeerIdentity));
1322 GNUNET_assert(address->prev == NULL);
1323 GNUNET_assert(address->next == NULL);
1324 GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address);
1325 GNUNET_CONTAINER_DLL_insert (mlp->peer_head, mlp->peer_tail, peer);
1326 mlp->c_p ++;
1327 GNUNET_STATISTICS_update (mlp->stats, "# peers in MLP", 1, GNUNET_NO);
1328 }
1329 else
1330 {
1331
1332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding address to peer `%s'\n",
1333 GNUNET_i2s (&address->peer));
1334
1335 GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address);
1336 }
1337 update_quality (mlp, address);
1338 }
1339 else
1340 {
1341 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating existing address to peer `%s'\n",
1342 GNUNET_i2s (&address->peer));
1343
1344 update_quality (mlp, address);
1345 }
1346
1347 /* Recalculate */
1348 if (new == GNUNET_YES)
1349 {
1350 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Recreating problem: new address\n");
1351
1352 mlp_delete_problem (mlp);
1353 mlp_create_problem (mlp, peers);
1354 mlp->presolver_required = GNUNET_YES;
1355 }
1356 if (mlp->auto_solve == GNUNET_YES)
1357 GAS_mlp_solve_problem (mlp, &ctx);
1358#endif
1359} 1295}
1360 1296
1361/** 1297/**
diff --git a/src/ats/test_ats_mlp_update.c b/src/ats/test_ats_mlp_update.c
new file mode 100644
index 000000000..4e1556266
--- /dev/null
+++ b/src/ats/test_ats_mlp_update.c
@@ -0,0 +1,255 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010,2011 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 * @file ats/test_ats_mlp_updating.c
22 * @brief basic test for updating ATS in MLP solver
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_statistics_service.h"
30#include "gnunet_ats_service.h"
31#include "gnunet-service-ats_addresses_mlp.h"
32#include "test_ats_api_common.h"
33
34/**
35 * Return value
36 */
37static int ret;
38
39/**
40 * MLP solver handle
41 */
42struct GAS_MLP_Handle *mlp;
43
44
45/**
46 * Statistics handle
47 */
48struct GNUNET_STATISTICS_Handle * stats;
49
50/**
51 * Hashmap containing addresses
52 */
53struct GNUNET_CONTAINER_MultiHashMap * addresses;
54
55/**
56 * Peer
57 */
58struct GNUNET_PeerIdentity p[2];
59
60/**
61 * ATS Address
62 */
63struct ATS_Address *address[3];
64
65/**
66 * Timeout task
67 */
68GNUNET_SCHEDULER_TaskIdentifier timeout_task;
69
70
71int addr_it (void *cls,
72 const struct GNUNET_HashCode * key,
73 void *value)
74{
75 struct ATS_Address *address = (struct ATS_Address *) value;
76 GAS_mlp_address_delete (mlp, addresses, address, GNUNET_NO);
77 GNUNET_CONTAINER_multihashmap_remove (addresses, key, value);
78 GNUNET_free (address);
79 return GNUNET_OK;
80}
81
82
83static void
84end_now (int res)
85{
86 if (GNUNET_SCHEDULER_NO_TASK != timeout_task)
87 {
88 GNUNET_SCHEDULER_cancel (timeout_task);
89 timeout_task = GNUNET_SCHEDULER_NO_TASK;
90 }
91 if (NULL != stats)
92 {
93 GNUNET_STATISTICS_destroy(stats, GNUNET_NO);
94 stats = NULL;
95 }
96 if (NULL != addresses)
97 {
98 GNUNET_CONTAINER_multihashmap_iterate (addresses, &addr_it, NULL);
99 GNUNET_CONTAINER_multihashmap_destroy (addresses);
100 addresses = NULL ;
101 }
102 if (NULL != mlp)
103 {
104 GAS_mlp_done (mlp);
105 mlp = NULL;
106 }
107
108 ret = res;
109}
110
111static void
112end_correctly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
113{
114 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Test ending with success\n"));
115 end_now (0);
116}
117
118static void
119end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
120{
121 GNUNET_break (0);
122 timeout_task = GNUNET_SCHEDULER_NO_TASK;
123 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Test ending with timeout\n"));
124 end_now (1);
125}
126
127
128static void
129bandwidth_changed_cb (void *cls, struct ATS_Address *address)
130{
131 static int cb_p0 = GNUNET_NO;
132
133 unsigned long long in = ntohl(address->assigned_bw_in.value__);
134 unsigned long long out = ntohl(address->assigned_bw_out.value__);
135
136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MLP suggests for peer `%s' address `%s':`%s' in %llu out %llu \n",
137 GNUNET_i2s(&address->peer),
138 address->plugin,
139 address->addr,
140 in, out);
141
142 if ((in > 0) && (out > 0) &&
143 (0 == memcmp(&p[0], &address->peer, sizeof (address->peer))))
144 cb_p0 ++;
145
146 if (1 == cb_p0)
147 GNUNET_SCHEDULER_add_now (&end_correctly, NULL);
148}
149
150
151static void
152check (void *cls, char *const *args, const char *cfgfile,
153 const struct GNUNET_CONFIGURATION_Handle *cfg)
154{
155 int quotas[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
156 unsigned long long quotas_in[GNUNET_ATS_NetworkTypeCount];
157 unsigned long long quotas_out[GNUNET_ATS_NetworkTypeCount];
158 struct GNUNET_ATS_Information ats;
159
160#if !HAVE_LIBGLPK
161 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!");
162 ret = 1;
163 return;
164#endif
165
166 timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
167
168 stats = GNUNET_STATISTICS_create("ats", cfg);
169 if (NULL == stats)
170 {
171 GNUNET_break (0);
172 end_now (1);
173 return;
174 }
175
176 /* Load quotas */
177 if (GNUNET_ATS_NetworkTypeCount != load_quotas (cfg, quotas_out, quotas_in,
178 GNUNET_ATS_NetworkTypeCount))
179 {
180 GNUNET_break (0);
181 end_now (1);
182 return;
183 }
184
185 /* Setup address hashmap */
186 addresses = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
187
188 /* Init MLP solver */
189 mlp = GAS_mlp_init (cfg, stats, quotas, quotas_out, quotas_in,
190 GNUNET_ATS_NetworkTypeCount, &bandwidth_changed_cb, NULL);
191 if (NULL == mlp)
192 {
193 GNUNET_break (0);
194 end_now (1);
195 return;
196 }
197 mlp->mlp_auto_solve = GNUNET_NO;
198
199 /* Create peer 0 */
200 if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p[0].hashPubKey))
201 {
202 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
203 end_now (1);
204 return;
205 }
206
207 /* Create address 0 */
208 address[0] = create_address (&p[0], "test_plugin0", "test_addr0", strlen("test_addr0")+1, 0);
209 if (NULL == address[0])
210 {
211 GNUNET_break (0);
212 end_now (1);
213 return;
214 }
215 GNUNET_CONTAINER_multihashmap_put (addresses, &p[0].hashPubKey, address[0],
216 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
217 /* Adding address 0 */
218 GAS_mlp_address_add (mlp, addresses, address[0]);
219
220 /* Updating address 0*/
221 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
222 ats.value = htonl (GNUNET_ATS_NET_WAN);
223 GAS_mlp_address_update (mlp, addresses, address[0], 1, GNUNET_NO, &ats, 1);
224
225 /* Retrieving preferred address for peer and wait for callback */
226 GAS_mlp_get_preferred_address (mlp, addresses, &p[0]);
227
228 GAS_mlp_solve_problem (mlp, addresses);
229}
230
231
232int
233main (int argc, char *argv[])
234{
235
236 static char *const argv2[] = { "test_ats_mlp_updating",
237 "-c",
238 "test_ats_mlp.conf",
239 "-L", "WARNING",
240 NULL
241 };
242
243 static struct GNUNET_GETOPT_CommandLineOption options[] = {
244 GNUNET_GETOPT_OPTION_END
245 };
246
247 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
248 "test_ats_mlp_updating", "nohelp", options,
249 &check, NULL);
250
251
252 return ret;
253}
254
255/* end of file test_ats_mlp_updating.c */