Files
kefu/im/server-fix-20260831/test_home_news_cache.php
T
2026-09-03 08:38:17 +08:00

45 lines
1.9 KiB
PHP

<?php
require __DIR__ . '/HomeNewsCache.php';
$directory = $argv[1];
if (!is_dir($directory)) {
mkdir($directory, 0700, true);
}
$file = $directory . '/news-list-v1.json';
$calls = 0;
$loader = function () use (&$calls) {
$calls++;
return array(array('news_id' => $calls, 'news_name' => 'Public article'));
};
function expect_cache($condition, $message)
{
if (!$condition) {
throw new Exception($message);
}
}
$first = txiaw_home_news_cached($directory, $loader);
$second = txiaw_home_news_cached($directory, $loader);
expect_cache($first === $second && $calls === 1, 'Fresh cache must avoid a second query');
file_put_contents($file, json_encode(array('created' => time() - 61, 'items' => $first)));
$third = txiaw_home_news_cached($directory, $loader);
expect_cache($calls === 2 && $third[0]['news_id'] === 2, 'Expired cache must refresh');
file_put_contents($file, json_encode(array('created' => time() - 61, 'items' => $third)));
$held = fopen($directory . '/news-list-v1.lock', 'c');
flock($held, LOCK_EX);
$started = microtime(true);
$stale = txiaw_home_news_cached($directory, $loader);
expect_cache($stale === $third && $calls === 2, 'Busy refresher must serve existing stale data');
expect_cache(microtime(true) - $started < 0.1, 'Stale read must not wait for the lock');
flock($held, LOCK_UN);
fclose($held);
$failedLoader = function () { throw new Exception('Simulated database failure'); };
expect_cache(txiaw_home_news_cached($directory, $failedLoader) === $third, 'Recent stale cache should survive a transient database failure');
file_put_contents($file, '{corrupt');
$recovered = txiaw_home_news_cached($directory, $loader);
expect_cache($calls === 3 && $recovered[0]['news_id'] === 3, 'Corrupt cache must recover');
expect_cache(txiaw_read_home_news_cache($file) !== false, 'Recovery must write a valid cache');
echo "PASS: cache hit, TTL refresh, nonblocking stale read, transient error fallback, corrupt cache recovery.\n";