3 # This file is part of the breadcrumbs daemon (bcd).
4 # Copyright (C) 2007 Pasqualino Ferrentino
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 # Contact: lino.ferrentino@yahoo.it (in Italian, English or German).
27 our @ISA = qw(t::TestCommonDb);
30 use Bcd
::Data
::StatementsStash
;
38 id_ant_nest
=> 1613499,
93 id_ant_nest
=> 1613499,
114 #this function should set up the "fake" users in this ant nest
118 #first of all I create the test ant nest
119 $self->_create_test_ant_nest(80128);
120 $self->_create_test_ant_nest(16134);
122 my $personal_data_id = Bcd
::Data
::Users
->create_personal_data_for_user($self->{stash
}, {});
127 my $id = $self->_create_a_test_user_for_trust($_, $personal_data_id);
128 push(@user_ids, $id);
131 #ok, now I should make the trusts
134 Bcd
::Data
::Trust
->create_trust_between
145 #this method simply creates a user, just to test
146 #returns the id of this user.
147 sub _create_a_test_user_for_trust
{
148 my ($self, $user, $personal_data_id) = @_;
150 my $ant_nest = exists($user->{id_ant_nest
}) ?
$user->{id_ant_nest
} : 8012899;
152 #the test db should be changed
153 my $sql = qq{insert into users
(nick
, id_ant_nest
,
154 users_state
, alfa
, bias
, id_personal_data
) values (?
, $ant_nest, 4, ?
, ?
, ?
)};
156 my $st = $self->{stash
}->get_connection()->prepare($sql);
158 $st->bind_param(1, $user->{nick
});
159 $st->bind_param(2, $user->{alfa
});
160 $st->bind_param(3, $user->{bias
});
161 $st->bind_param(4, $personal_data_id);
164 my $id_of_insertion = $self->{stash
}->get_id_of_last_user();
166 return $id_of_insertion;
169 #this is the only test which uses this fixture, so I create the fixture only once
170 #but it is shared by all the test inside this file
174 $self->_test_is_valid_trust();
175 $self->_test_is_valid_trust_bb();
176 $self->_test_exists_direct_trust_between();
177 $self->_test_simple_path();
178 $self->_test_composite_paths();
179 $self->_test_simple_trusts();
180 $self->_test_composite_trusts();
181 $self->_test_no_path_trust();
182 $self->_test_reachables_no_limit();
183 $self->_test_get_maximum_reachable_set();
184 $self->_test_reachables_with_limit();
186 $self->_test_get_trust();
188 $self->_test_incoming_net();
189 $self->_test_outgoing_net();
191 #these tests MUST be run in sequence.
192 $self->_test_new_booking();
193 $self->_test_create_new_trust();
194 $self->_test_change_trust();
195 $self->_test_rollback_change_trust();
196 $self->_test_commit_trust_changes();
197 $self->_test_get_backupped_trusts();
200 sub _test_outgoing_net
{
202 my $stash = $self->{stash
};
205 #print "_________________________ test outgoing net\n";
207 $outgoing_net = Bcd
::Data
::Trust
->get_outgoing_trust_net($stash, $user_ids[5]);
208 $self->assert_equals(8, scalar(keys(%{$outgoing_net})));
209 #print Dumper($outgoing_net);
211 my $trust_4 = $outgoing_net->{$user_ids[4]};
212 $self->assert_str_equals("8.33853676860981e-06", $trust_4->[2]);
214 my $trust_8 = $outgoing_net->{$user_ids[8]};
215 $self->assert_str_equals("0.000245666165323859", $trust_8->[2]);
217 #print "_________________________ test outgoing net END!\n";
221 sub _test_incoming_net
{
223 my $stash = $self->{stash
};
226 #print "_________________________ test incoming_net\n";
227 #print Dumper (\@user_ids);
229 $incoming_net = Bcd
::Data
::Trust
->get_incoming_trust_net($stash, $user_ids[5]);
230 $self->assert_equals(8, scalar(keys(%{$incoming_net})));
232 #print "||||||||||||||||||||||||||||||||||||||||||||||||||| end count\n";
233 #print "the net is\n";
234 #print Dumper($incoming_net);
236 #ok, I take the path from the most distant people, just to test...
237 my $trust_4 = $incoming_net->{$user_ids[4]};
239 #print Dumper($trust_4);
240 $self->assert_str_equals("0.00770656129838086", $trust_4->[2]);
242 my $trust_8 = $incoming_net->{$user_ids[8]};
243 $self->assert_str_equals("0.00688167479645286", $trust_8->[2]);
249 my $stash = $self->{stash
};
252 my ($trust, $am_i_second) = Bcd
::Data
::Trust
->_get_trust_between($stash, $user_ids[1], $user_ids[5]);
254 $self->assert_equals("0.99", $trust);
255 $self->assert_equals("0", $am_i_second);
257 ($trust, $am_i_second) = Bcd
::Data
::Trust
->_get_trust_between($stash, $user_ids[5], $user_ids[1]);
259 $self->assert_equals("0.60", $trust);
260 $self->assert_equals("1", $am_i_second);
264 sub _test_new_booking
{
266 my $stash = $self->{stash
};
269 Bcd
::Data
::Trust
->create_new_trust_booking($stash, 5, 7, 0.43);
271 my $sql = qq{select * from trusts_bookings where u1
= ?
and u2
= ?
};
273 my $st = $stash->get_connection()->prepare($sql);
275 $st->bind_param(1, 5);
276 $st->bind_param(2, 7);
280 my $ref = $st->fetchrow_arrayref();
281 $self->assert_equals("0.43", $ref->[2]);
285 sub _test_create_new_trust
{
288 my $stash = $self->{stash
};
291 #this is useless, because in this module the tests are run in sequence...
292 #and so this row has been already put by the preceding test
293 #Bcd::Data::Trust->create_new_trust_booking($stash, 5, 7, 0.43);
296 #ok, now let's create the inverse trust
297 Bcd
::Data
::Trust
->create_new_trust($stash, 7, 5, 0.98);
299 #there should be a new row in the trust table
300 my $sql = qq{select * from trusts where u1
=?
and u2
= ?
};
301 my $st = $stash->get_connection()->prepare($sql);
302 $st->bind_param(1, 5);
303 $st->bind_param(2, 7);
306 my $row = $st->fetchrow_arrayref();
309 $self->assert_equals("0.43", $row->[2]);
310 $self->assert_equals("0.98", $row->[3]);
313 #then I should assert myself that the booking has been deleted
314 $sql = qq{select * from trusts_bookings where u1
=?
and u2
= ?
};
315 $st = $stash->get_connection()->prepare($sql);
316 $st->bind_param(1, 5);
317 $st->bind_param(2, 7);
320 $row = $st->fetchrow_arrayref();
323 $self->assert_null($row); #nothing.
327 sub _test_change_trust
{
329 my $stash = $self->{stash
};
332 #ok, now let's try to change the trust of the first user
333 Bcd
::Data
::Trust
->change_trust($stash, 5, 7, 0.66);
336 #I should have a row in the trusts_backups table
337 my $sql = qq{SELECT
* from trusts_backups where u1
=? AND u2
=?
};
338 my $st_select_backup = $stash->get_connection()->prepare($sql);
340 $st_select_backup->bind_param(1, 5);
341 $st_select_backup->bind_param(2, 7);
343 $st_select_backup->execute();
344 my $row = $st_select_backup->fetchrow_arrayref();
346 #I should have the backup...
347 $self->assert_equals("0.43", $row->[2]);
349 #AND i have the trust changed in the trust table
350 $sql = qq{SELECT
* from trusts where u1
=? AND u2
=?
};
351 my $st_select_trust = $stash->get_connection()->prepare($sql);
353 $st_select_trust->bind_param(1, 5);
354 $st_select_trust->bind_param(2, 7);
356 $st_select_trust->execute();
357 $row = $st_select_trust->fetchrow_arrayref();
359 #I should have the new trust
360 $self->assert_equals("0.66", $row->[2]);
362 #####################################################
364 #let's try to change the trust once again
365 Bcd
::Data
::Trust
->change_trust($stash, 5, 7, 0.44);
367 $st_select_backup->bind_param(1, 5);
368 $st_select_backup->bind_param(2, 7);
370 $st_select_backup->execute();
371 $row = $st_select_backup->fetchrow_arrayref();
373 #I should have the backup, unchanged
374 $self->assert_equals("0.43", $row->[2]);
376 #AND i have the trust changed in the trust table
377 $st_select_trust->bind_param(1, 5);
378 $st_select_trust->bind_param(2, 7);
380 $st_select_trust->execute();
381 $row = $st_select_trust->fetchrow_arrayref();
383 #I should have the new trust
384 $self->assert_equals("0.44", $row->[2]);
386 ###################################################
387 ## let's try to change the trust for the second user
388 #let's try to change the trust once again
389 Bcd
::Data
::Trust
->change_trust($stash, 7, 5, 0.12);
391 $st_select_backup->bind_param(1, 7);
392 $st_select_backup->bind_param(2, 5);
394 $st_select_backup->execute();
395 $row = $st_select_backup->fetchrow_arrayref();
397 #I should have the backup
398 $self->assert_equals("0.98", $row->[2]);
400 #AND i have the trust changed in the trust table
401 $st_select_trust->bind_param(1, 5);
402 $st_select_trust->bind_param(2, 7);
404 $st_select_trust->execute();
405 $row = $st_select_trust->fetchrow_arrayref();
407 #I should have the new trust
408 $self->assert_equals("0.12", $row->[3]);
411 #################################################
412 ## second change for the second user
414 Bcd
::Data
::Trust
->change_trust($stash, 7, 5, 0.11);
416 $st_select_backup->bind_param(1, 7);
417 $st_select_backup->bind_param(2, 5);
419 $st_select_backup->execute();
420 $row = $st_select_backup->fetchrow_arrayref();
422 #I should have the backup, unchanged
423 $self->assert_equals("0.98", $row->[2]);
425 #AND i have the trust changed in the trust table
426 $st_select_trust->bind_param(1, 5);
427 $st_select_trust->bind_param(2, 7);
429 $st_select_trust->execute();
430 $row = $st_select_trust->fetchrow_arrayref();
432 #I should have the new trust
433 $self->assert_equals("0.11", $row->[3]);
437 sub _test_rollback_change_trust
{
439 my $stash = $self->{stash
};
443 Bcd
::Data
::Trust
->change_trust($stash, $user_ids[5], $user_ids[1], 0.25);
444 Bcd
::Data
::Trust
->change_trust($stash, $user_ids[5], $user_ids[6], 0.22);
446 my ($trust, $am_i_second) = Bcd
::Data
::Trust
->_get_trust_between($stash, $user_ids[5], $user_ids[1]);
447 $self->assert_equals("0.25", $trust);
448 $self->assert_equals("1", $am_i_second);
450 Bcd
::Data
::Trust
->rollback_trust_changes($stash, $user_ids[5]);
452 #ok, now I should have the old trusts...
453 ($trust, $am_i_second) = Bcd
::Data
::Trust
->_get_trust_between($stash, $user_ids[5], $user_ids[1]);
455 $self->assert_equals("0.60", $trust);
456 $self->assert_equals("1", $am_i_second);
458 ($trust, $am_i_second) = Bcd
::Data
::Trust
->_get_trust_between($stash, $user_ids[5], $user_ids[6]);
460 $self->assert_equals("0.99", $trust);
461 $self->assert_equals("0", $am_i_second);
463 #then I should see that the rollbacks are deleted...
464 my $sql = qq{SELECT
* from trusts_backups where u1
=?
};
465 my $st_select_backup = $stash->get_connection()->prepare($sql);
467 $st_select_backup->bind_param(1, $user_ids[5]);
468 $st_select_backup->execute();
470 my $row = $st_select_backup->fetchrow_arrayref();
472 $self->assert_null($row);
476 sub _test_commit_trust_changes
{
479 my $stash = $self->{stash
};
483 Bcd
::Data
::Trust
->change_trust($stash, $user_ids[5], $user_ids[1], 0.25);
484 Bcd
::Data
::Trust
->change_trust($stash, $user_ids[5], $user_ids[6], 0.22);
487 Bcd
::Data
::Trust
->commit_trust_changes($stash, $user_ids[5]);
489 #ok, if I make another change the previous change is the backup
490 Bcd
::Data
::Trust
->change_trust($stash, $user_ids[5], $user_ids[1], 0.24);
492 my ($trust, $am_i_second) = Bcd
::Data
::Trust
->_get_trust_between($stash, $user_ids[5], $user_ids[1]);
493 $self->assert_equals("0.24", $trust);
494 $self->assert_equals("1", $am_i_second);
496 my $sql = qq{SELECT
* from trusts_backups where u1
=?
};
497 my $st_select_backup = $stash->get_connection()->prepare($sql);
499 $st_select_backup->bind_param(1, $user_ids[5]);
500 $st_select_backup->execute();
502 my $row = $st_select_backup->fetchrow_arrayref();
504 $self->assert_equals("0.25", $row->[2]);
505 $self->assert_equals("1", $row->[3]);
511 sub _test_get_backupped_trusts
{
513 my $stash = $self->{stash
};
516 Bcd
::Data
::Trust
->commit_trust_changes($stash, $user_ids[5]);
518 my ($trust51_old, $am_i_second1) = Bcd
::Data
::Trust
->_get_trust_between($stash, $user_ids[5], $user_ids[1]);
519 my ($trust56_old, $am_i_second2) = Bcd
::Data
::Trust
->_get_trust_between($stash, $user_ids[5], $user_ids[6]);
522 Bcd
::Data
::Trust
->change_trust($stash, $user_ids[5], $user_ids[1], 0.55);
523 Bcd
::Data
::Trust
->change_trust($stash, $user_ids[5], $user_ids[6], 0.33);
525 my $backups = Bcd
::Data
::Trust
->get_user_backupped_trusts($stash, $user_ids[5]);
527 $self->assert_equals($trust51_old, $backups->{$user_ids[1]});
528 $self->assert_equals($trust56_old, $backups->{$user_ids[6]});
533 sub _test_exists_direct_trust_between
{
535 my $stash = $self->{stash
};
538 my $res = Bcd
::Data
::Trust
->exists_direct_trust_between
539 ($stash, $user_ids[1],$user_ids[2]);
540 $self->assert_num_equals(1, $res);
542 $res = Bcd
::Data
::Trust
->exists_direct_trust_between
543 ($stash, $user_ids[1], $user_ids[6]);
544 $self->assert_num_equals(0, $res);
547 sub _test_simple_path
{
549 my $stash = $self->{stash
};
552 my ($res, $path) = Bcd
::Data
::Trust
->get_path($user_ids[1], $user_ids[1], $stash);
553 $self->assert_num_equals(1, $res);
554 $self->assert_num_equals($user_ids[1], $path->[0]->[0]);
557 ($res, $path) = Bcd
::Data
::Trust
->get_path($user_ids[1], $user_ids[6], $stash);
558 $self->assert_num_equals(1, $res);
559 $self->assert_num_equals($user_ids[1], $path->[0]->[0]);
560 $self->assert_num_equals($user_ids[5], $path->[1]->[0]);
561 $self->assert_num_equals($user_ids[6], $path->[2]->[0]);
564 ($res ,$path) = Bcd
::Data
::Trust
->get_path($user_ids[2], $user_ids[8], $stash);
566 $self->assert_num_equals(1, $res);
567 $self->assert_num_equals($user_ids[2], $path->[0]->[0]);
568 $self->assert_num_equals($user_ids[1], $path->[1]->[0]);
569 $self->assert_num_equals($user_ids[5], $path->[2]->[0]);
570 $self->assert_num_equals($user_ids[6], $path->[3]->[0]);
571 $self->assert_num_equals($user_ids[7], $path->[4]->[0]);
572 $self->assert_num_equals($user_ids[8], $path->[5]->[0]);
574 ($res ,$path) = Bcd
::Data
::Trust
->get_path($user_ids[8],$user_ids[2], $stash);
577 $self->assert_num_equals(1, $res);
578 $self->assert_num_equals($user_ids[8], $path->[0]->[0]);
579 $self->assert_num_equals($user_ids[7], $path->[1]->[0]);
580 $self->assert_num_equals($user_ids[6], $path->[2]->[0]);
581 $self->assert_num_equals($user_ids[5], $path->[3]->[0]);
582 $self->assert_num_equals($user_ids[1], $path->[4]->[0]);
583 $self->assert_num_equals($user_ids[2], $path->[5]->[0]);
585 ($res ,$path) = Bcd
::Data
::Trust
->get_path($user_ids[1],$user_ids[4], $stash);
586 $self->assert_num_equals(1, $res);
587 $self->assert_num_equals($user_ids[1], $path->[0]->[0]);
588 $self->assert_num_equals($user_ids[2], $path->[1]->[0]);
591 sub _test_composite_paths
{
593 my $stash = $self->{stash
};
596 #I add some other trusts... and see what happens
597 my $sql = qq{insert into trusts
values($user_ids[7],$user_ids[1],0.78,0.88)};
598 my $st = $self->{stash
}->get_connection()->prepare($sql);
603 ($res ,$path) = Bcd
::Data
::Trust
->get_path($user_ids[2],$user_ids[7], $stash);
604 $self->assert_num_equals(1, $res);
605 $self->_check_path([2, 1, 7], $path);
607 ($res ,$path) = Bcd
::Data
::Trust
->get_path($user_ids[8], $user_ids[3], $stash);
608 $self->assert_num_equals(1, $res);
609 $self->_check_path([8, 7, 1, 3], $path);
612 #$self->{"conn"}->rollback();
613 #you cannot rollback, with a rollback you erase the entire fixture.
615 #I simply delete the row
616 $sql = qq{DELETE from trusts where u1
=$user_ids[7] and u2
=$user_ids[1]};
617 $st = $self->{stash
}->get_connection()->prepare($sql);
620 #the old path, without the new trust...
621 ($res ,$path) = Bcd
::Data
::Trust
->get_path($user_ids[2], $user_ids[7], $stash);
622 $self->assert_num_equals(1, $res);
623 $self->_check_path([2, 1, 5, 6, 7], $path);
627 my ($self, $path_to_check, $returned_path) = @_;
630 foreach (@
{$path_to_check}){
631 $self->assert_num_equals($user_ids[$_], $returned_path->[$index]->[0]);
636 # #this should test some simple trusts...
637 sub _test_simple_trusts
{
640 my $stash = $self->{stash
};
643 #the trust with myself is one -> 100bB
644 $trust = Bcd
::Data
::Trust
->get_trust($user_ids[2],$user_ids[2], $stash);
645 $self->assert_num_equals(100, $trust);
647 $trust = Bcd
::Data
::Trust
->get_trust($user_ids[1], $user_ids[3], $stash);
648 $self->assert_num_equals(98.55, $trust);
652 sub _test_composite_trusts
{
654 my $stash = $self->{stash
};
658 $trust = Bcd
::Data
::Trust
->get_trust($user_ids[3], $user_ids[2], $stash);
659 $self->assert_num_equals(99.64, $trust);
661 $trust = Bcd
::Data
::Trust
->get_trust($user_ids[3], $user_ids[6], $stash);
662 $self->assert_num_equals(83.41, $trust);
664 $trust = Bcd
::Data
::Trust
->get_trust($user_ids[3], $user_ids[7], $stash);
665 $self->assert_num_equals(45.99, $trust);
667 $trust = Bcd
::Data
::Trust
->get_trust($user_ids[3], $user_ids[8], $stash);
668 $self->assert_num_equals(3.60, $trust);
670 $trust = Bcd
::Data
::Trust
->get_trust($user_ids[1], $user_ids[6], $stash);
671 $self->assert_num_equals(94.43, $trust);
674 sub _test_no_path_trust
{
678 #the trust with a not existing path is zero
679 $trust = Bcd
::Data
::Trust
->get_trust_decimal($user_ids[3], $user_ids[0] , $self->{stash
});
680 $self->assert_num_equals(0, $trust);
684 #this hash is a precomputed set from some users in the test ant nest
685 my $expected_set_from_user_1 = {
695 sub _check_reachable_set_from_user
{
696 my ($self, $expected_list_of_reachable_ants, $expectd_set, $returned_set) = @_;
698 $self->assert_num_equals($#{$expected_list_of_reachable_ants}+1, scalar(keys(%{$returned_set})));
700 for (@
{$expected_list_of_reachable_ants}){
701 $self->assert_str_equals(
704 substr($returned_set->{$user_ids[$_]}, 0, length($expectd_set->{$_}))
710 sub _test_reachables_no_limit
{
713 my $stash = $self->{stash
};
716 $hash = Bcd
::Data
::Trust
->get_reachable_users_from_user_trust_no_limit($user_ids[1], 0.7060, $stash);
717 $self->_check_reachable_set_from_user([3, 2, 5, 9], $expected_set_from_user_1, $hash);
719 $hash = Bcd
::Data
::Trust
->get_reachable_users_from_user_trust_no_limit($user_ids[1], 0.26, $stash);
720 $self->_check_reachable_set_from_user([3, 2, 5, 9, 6], $expected_set_from_user_1, $hash);
722 $hash = Bcd
::Data
::Trust
->get_reachable_users_from_user_trust_no_limit($user_ids[1], 0.00003, $stash);
723 $self->_check_reachable_set_from_user([3, 2, 4, 5, 9, 6, 7], $expected_set_from_user_1, $hash);
725 $hash = Bcd
::Data
::Trust
->get_reachable_users_from_user_trust_no_limit($user_ids[0], 0.03, $stash);
726 $self->_check_reachable_set_from_user([], $expected_set_from_user_1, $hash);
729 sub _test_reachables_with_limit
{
732 my $stash = $self->{stash
};
734 #I should NOT reach the ant in the other ant nest
735 $hash = Bcd
::Data
::Trust
->get_reachable_users_from_user_trust_limited($user_ids[1], 0.7060, $stash);
736 $self->_check_reachable_set_from_user([3, 2, 5], $expected_set_from_user_1, $hash);
738 $hash = Bcd
::Data
::Trust
->get_reachable_users_from_user_trust_limited($user_ids[1], 0.26, $stash);
739 $self->_check_reachable_set_from_user([3, 2, 5, 6], $expected_set_from_user_1, $hash);
741 $hash = Bcd
::Data
::Trust
->get_reachable_users_from_user_trust_limited($user_ids[1], 0.00003, $stash);
742 $self->_check_reachable_set_from_user([3, 2, 5, 6, 7, 4], $expected_set_from_user_1, $hash);
745 sub _test_get_maximum_reachable_set
{
747 my $stash = $self->{"stash"};
749 my $maximum_set = Bcd
::Data
::Trust
->_get_maximum_reachable_set($user_ids[5], $stash);
751 #the maximum set should be equal to all the test set
754 if (!defined($_->{id_ant_nest
})){
755 $self->assert_not_null($maximum_set->{$user_ids[$index]});
761 sub _test_is_valid_trust
{
763 my $stash = $self->{"stash"};
765 $self->assert_num_equals(1, Bcd
::Data
::Trust
->is_valid_trust(0.5));
766 $self->assert_num_equals(0, Bcd
::Data
::Trust
->is_valid_trust(0));
767 $self->assert_num_equals(0, Bcd
::Data
::Trust
->is_valid_trust(-0.5));
768 $self->assert_num_equals(1, Bcd
::Data
::Trust
->is_valid_trust(1));
769 $self->assert_num_equals(0, Bcd
::Data
::Trust
->is_valid_trust(1.5));
772 sub _test_is_valid_trust_bb
{
775 my $stash = $self->{"stash"};
777 $self->assert_num_equals(1, Bcd
::Data
::Trust
->is_valid_trust_bb(0.5));
778 $self->assert_num_equals(1, Bcd
::Data
::Trust
->is_valid_trust_bb(0));
779 $self->assert_num_equals(1, Bcd
::Data
::Trust
->is_valid_trust_bb(-0.5));
780 $self->assert_num_equals(1, Bcd
::Data
::Trust
->is_valid_trust_bb(100));
781 $self->assert_num_equals(1, Bcd
::Data
::Trust
->is_valid_trust_bb(-100));
782 $self->assert_num_equals(0, Bcd
::Data
::Trust
->is_valid_trust_bb(150));