# t/uniqcookie.t # # Test LJ::UniqCookie. # # This code was forked from the LiveJournal project owned and operated # by Live Journal, Inc. The code has been modified and expanded by # Dreamwidth Studios, LLC. These files were originally licensed under # the terms of the license supplied by Live Journal, Inc, which can # currently be found at: # # http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt # # In accordance with the original license, this code and all its # modifications are provided under the GNU General Public License. # A copy of that license can be found in the LICENSE file included as # part of this distribution. use strict; use warnings; use Test::More tests => 48; BEGIN { $LJ::_T_CONFIG = 1; require "$ENV{LJHOME}/cgi-bin/ljlib.pl"; } use LJ::Test qw(temp_user memcache_stress); use LJ::UniqCookie; sub run_tests { my $class = "LJ::UniqCookie"; my $get_uniq = sub { $class->generate_uniq_ident; }; # tell LJ::UniqCookie how to generate unixtimes for uniqmap rows my $time_ct = time() - 30; $LJ::_T_UNIQCOOKIE_MODTIME_CB = sub { return $time_ct++; }; # don't lazy clean until we're ready to explicitly test it $LJ::_T_UNIQCOOKIE_LAZY_CLEAN_PCT = -1; { # one uniq, one user my $u = temp_user(); my $uniq = $get_uniq->(); ok( $class->save_mapping( $uniq => $u ), "saved mapping" ); my $uid = $class->load_mapping( uniq => $uniq ); ok( $uid == $u->id, "loaded by uniq" ); my $new_uniq = $class->load_mapping( user => $u ); ok( $new_uniq eq $uniq, "loaded by u ser" ); $LJ::_T_UNIQCOOKIE_CURRENT_UNIQ = $uniq; my $g_remote = $class->guess_remote; ok( $u->equals($g_remote), "guessed correct remote" ); } { # multiple uniqs, same user my $u = temp_user(); my @added_uniqs; foreach ( 1 .. 5 ) { my $uniq = $get_uniq->(); $class->save_mapping( $uniq => $u ); push @added_uniqs, $uniq; } my @got_uniqs = $class->load_mapping( user => $u ); ok( eq_set( \@added_uniqs, \@got_uniqs ), "got multiple uniqs for a user" ); } { # multiple users, same uniq my $uniq = $get_uniq->(); my @userids; foreach ( 1 .. 5 ) { my $u = temp_user(); $class->save_mapping( $uniq => $u ); push @userids, $u->id; } my @got_userids = $class->load_mapping( uniq => $uniq ); ok( eq_set( \@got_userids, \@userids ), "got multiple users for a uniq" ); } { # multiple uniqs, multiple users my $u = temp_user(); my $u2 = temp_user(); my @uniq_added; my @uniq_added_u2; foreach ( 1 .. 5 ) { my $uniq = $get_uniq->(); $class->save_mapping( $uniq => $u ); push @uniq_added, $uniq; if ( rand() > 0.5 ) { $class->save_mapping( $uniq => $u2 ); push @uniq_added_u2, $uniq; } } my @uniq_list = $class->load_mapping( user => $u ); ok( eq_set( \@uniq_added, \@uniq_list ), "saved some uniqs, got the same back" ); my @uniq_list2 = $class->load_mapping( user => $u2 ); ok( eq_set( \@uniq_added, \@uniq_list ), "saved uniqs to another user, got the same back" ); } # set up a delete callback which will tell us the number # of rows deleted in the last cleaning operation my $last_delete_ct = 0; $LJ::_T_UNIQCOOKIE_DELETE_CB = sub { my ( $type, $ct ) = @_; $last_delete_ct = $ct; }; { # cleaning per-user my $u = temp_user(); my @added_uniqs; foreach ( 1 .. 25 ) { my $uniq = $get_uniq->(); $class->save_mapping( $uniq => $u ); push @added_uniqs, $uniq; } my @got_uniqs = $class->load_mapping( user => $u ); my @added_trim = ( reverse @added_uniqs )[ 0 .. 9 ]; ok( eq_set( \@added_trim, \@got_uniqs ), "cleaned multiple uniqs for a user" ); ok( $last_delete_ct == 15, "deleted correct number of rows by user" ); # shouldn't clean this time around LJ::DB::no_cache( sub { $class->clear_request_cache; $class->load_mapping( user => $u ); } ); ok( $last_delete_ct == 0, "loaded by user without redundant cleaning" ); } { # cleaning per-uniq my $uniq = $get_uniq->(); my @userids; foreach ( 1 .. 25 ) { my $u = temp_user(); $class->save_mapping( $uniq => $u ); push @userids, $u->id; } my @got_userids = $class->load_mapping( uniq => $uniq ); my @userids_trim = ( reverse @userids )[ 0 .. 9 ]; ok( eq_set( \@userids_trim, \@got_userids ), "cleaned multiple users for a uniq" ); ok( $last_delete_ct == 15, "deleted correct number of rows by uniq" ); # shouldn't clean this time around LJ::DB::no_cache( sub { $class->clear_request_cache; $class->load_mapping( uniq => $uniq ); } ); ok( $last_delete_ct == 0, "loaded by uniq without redundant cleaning" ); } { # lazy cleaning my $u = temp_user(); my $dirty = 0; $last_delete_ct = 0; # reset this foreach ( 1 .. 25 ) { my $uniq = $get_uniq->(); $class->save_mapping( $uniq, $u ); # ... but there should be 0 rows deleted $dirty = 1 if $last_delete_ct > 0; } ok( !$dirty, "lazy cleaning rand-false case works" ); # ready to test this, let's set it on now $LJ::_T_UNIQCOOKIE_LAZY_CLEAN_PCT = 1.00; my $uniq = $get_uniq->(); $class->save_mapping( $uniq, $u ); ok( $last_delete_ct > 0, "lazy cleaning rand-true case works" ); } } memcache_stress { run_tests(); };