perl-Cache-Cache-1.06-16.fc22 sometimes fails to build in F22 because t/6_test_size_aware_memory_cache.t fails: t/5_test_size_aware_file_cache.t ........... ok defined(@array) is deprecated at /builddir/build/BUILD/Cache-Cache-1.06/blib/lib/Cache/CacheTester.pm line 580. (Maybe you should just omit the defined()?) Couldn't limit size to 28 at /builddir/build/BUILD/Cache-Cache-1.06/blib/lib/Cache/CacheSizer.pm line 92. Couldn't limit size to 28 at /builddir/build/BUILD/Cache-Cache-1.06/blib/lib/Cache/CacheSizer.pm line 92. Use of uninitialized value $first_value in string eq at /builddir/build/BUILD/Cache-Cache-1.06/blib/lib/Cache/SizeAwareCacheTester.pm line 151. t/6_test_size_aware_memory_cache.t ......... Failed 1/48 subtests This could be time race similar to bug #1112553.
I cannot explain this failure as a bug in tests. (I found another flaw in the tests but it's irrelevant to this failure.) This failure says the looked-up key does exist in the cache, but that should be possible only (1) when the key expires or (2) when the cache size exceeds a size limit. The (1) case is covered by my previous patch introducing check for elapsed time. The (2) case is suspicious as "Couldn't limit size" warnings were reported. Or it's a genuine bug in the library.
After reading Cache::CacheSizer::_Limit_Size(): sub _Limit_Size { my ( $p_cache, $p_cache_meta_data, $p_new_size ) = @_; Assert_Defined( $p_cache ); Assert_Defined( $p_cache_meta_data ); Assert_Defined( $p_new_size ); $p_new_size >= 0 or throw Error::Simple( "p_new_size >= 0 required" ); my $size_estimate = $p_cache_meta_data->get_cache_size( ); return if $size_estimate <= $p_new_size; foreach my $key ( $p_cache_meta_data->build_removal_list( ) ) { return if $size_estimate <= $p_new_size; $size_estimate -= $p_cache_meta_data->build_object_size( $key ); $p_cache->remove( $key ); $p_cache_meta_data->remove( $key ); } warn( "Couldn't limit size to $p_new_size" ); } It's clear that $cache->limit_size() call from the tests removed all cache keys and still could not press the cache size under size it previously had with the first key. So later fetch could not find the key. It's possible that the first key queued in front of other keys because in the build_removal_list(), so it got removed before any of them. This is flaw in the test. However the reason why limit_size() could not decrease size while keeping at least on key in the Cache is unclear to me.
The unexpected dequeuing can be reproduced by: --- a/lib/Cache/SizeAwareCacheTester.pm +++ b/lib/Cache/SizeAwareCacheTester.pm @@ -119,6 +119,7 @@ sub _test_two $self->ok( ) : $self->not_ok( '$first_size > $empty_size' ); my $second_expires_in = $first_expires_in / 2; + sleep ($second_expires_in + 1); my $num_keys = 5;