/'. No such // fixtures exist here, so lookups miss and the code falls back to FFMPEG_BIN_40. if (!defined('BIN_PATH')) { define('BIN_PATH', $binRoot . '/'); } if (!defined('VOD_PATH')) { define('VOD_PATH', $tmpRoot . '/vod/'); } if (!is_dir(VOD_PATH)) { mkdir(VOD_PATH, 0775, true); } // VodItemImporter keeps its TMDb caches and per-series locks here. if (!defined('WATCH_TMP_PATH')) { define('WATCH_TMP_PATH', $tmpRoot . '/watch/'); } if (!is_dir(WATCH_TMP_PATH)) { mkdir(WATCH_TMP_PATH, 0775, true); } foreach (array('40', '71', '80') as $version) { $ffmpegConst = 'FFMPEG_BIN_' . $version; $ffprobeConst = 'FFPROBE_BIN_' . $version; if (!defined($ffmpegConst)) { define($ffmpegConst, $fakeBinary); } if (!defined($ffprobeConst)) { define($ffprobeConst, $fakeBinary); } } if (!isset($_FILES)) { $_FILES = array(); } if (!function_exists('igbinary_serialize')) { function igbinary_serialize($value) { return serialize($value); } } if (!function_exists('igbinary_unserialize')) { function igbinary_unserialize($value) { return unserialize($value); } } // Child PHP processes that fake \XC_VM in an auto_prepend_file cannot start with // the real xcvm_core loaded (the class would already exist). On a host whose // php.ini loads it (the bundled PHP) hand them a copy of that ini without it; // elsewhere (CI) the plain binary. if (!function_exists('xcvm_test_child_php')) { /** @return list */ function xcvm_test_child_php(): array { $ini = php_ini_loaded_file(); if ($ini === false || !extension_loaded('xcvm_core')) { return array(PHP_BINARY); } $copy = __DIR__ . '/.tmp/php-no-xcvm_core.ini'; file_put_contents($copy, preg_replace('/^\s*(zend_)?extension\s*=.*xcvm_core.*$/m', '', (string) file_get_contents($ini))); return array(PHP_BINARY, '-c', $copy); } } require_once MAIN_HOME . 'vendor/autoload.php'; require_once __DIR__ . '/Unit/M3uParser/ExtCustomTag.php'; // Test support: the MariaDB/MySQL harness (TestDb) for DB-touching repositories/services. require_once __DIR__ . '/Support/TestDb.php'; require_once __DIR__ . '/Support/ClusterReference.php'; require_once __DIR__ . '/Support/FakeClusterCrypto.php'; require_once __DIR__ . '/Support/FakeSshFleet.php'; require_once __DIR__ . '/Support/BusServer.php'; require_once __DIR__ . '/Support/RedisServer.php'; require_once __DIR__ . '/Support/QueryLogDb.php'; require_once __DIR__ . '/Support/InstallSchema.php'; require_once __DIR__ . '/Support/ReplicaFixture.php'; require_once __DIR__ . '/Support/TestSourceDriver.php'; require_once __DIR__ . '/Support/AgentUser.php'; require_once __DIR__ . '/Support/NodeLeaseFixture.php'; require_once __DIR__ . '/Support/FakeTmdbClient.php'; require_once __DIR__ . '/Support/ResellerAjax.php'; // EventIngest's lane locks are real flock files. Without this they would land // in the shared TMP_PATH or system temp dir, where suite runs from other // checkouts contend on the same files: give each test process its own // directory under tests/.tmp, removed when the process ends. $ingestLockDir = $tmpRoot . '/cluster_ingest/' . getmypid() . '/'; \XcVm\Domain\Cluster\EventIngest::useLockDir($ingestLockDir); register_shutdown_function(static function () use ($ingestLockDir): void { foreach (glob($ingestLockDir . '*') ?: array() as $lockFile) { @unlink($lockFile); } @rmdir($ingestLockDir); }); // The node replica's ETag cache (ReplicaEtagCache) lives in TMP_PATH, which // some tests define as a shared path, and many tests fix the cluster clock at // the same instant, so a cached section would outlive the test that built it: // off for the suite; a test that checks the caching gives it a directory. \XcVm\Core\Cluster\ReplicaEtagCache::useDir(false); // The settings-miss audit (SettingsAudit) counts reads on nodes in mode 1 or // 2, and many tests point NodeFlows at such a file: off for the suite; a // test that checks it gives it its own directories. \XcVm\Core\Cluster\SettingsAudit::useDir(false); // The connect audit (ConnectAudit) counts connects on nodes in mode 1 or 2, // in STORAGE_PATH, which some tests define as a shared path: off for the // suite; a test that checks it gives it its own directory. \XcVm\Core\Cluster\ConnectAudit::useDir(false); // cluster:exec writes each refusal to STDERR for the agent's log, which PHPUnit // does not capture: the refusals the negative tests provoke go to a buffer instead. \XcVm\Cli\Commands\ClusterExecCommand::useErrors(fopen('php://memory', 'w+')); // The node's own store of its streams' runtime state (StreamRuntime) defaults // to the deploy's config/cluster/runtime/, and every stream state write with // STREAMS off lapses it (or with STREAMS on keeps into it): a per-run // directory under tests/.tmp, removed when the process ends, so no test // touches an install on this machine. A test that checks the store gives it // its own directory and restores this one (StreamRuntime::dir()) after. $runtimeDir = $tmpRoot . '/cluster_runtime/' . getmypid() . '/'; \XcVm\Core\Cluster\StreamRuntime::useDir($runtimeDir); register_shutdown_function(static function () use ($runtimeDir): void { exec('rm -rf ' . escapeshellarg($runtimeDir)); });