mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-11-07 11:03:41 +01:00
p5 bundled four feature PRs; two of them broke real panels. 1. On-demand streams fail to open when idle (web player times out), while a stream already running plays fine. PR #380 made the unsupervised (fanout-off / PHP-monitor) launcher run the native remuxer for the DEFAULT fanout_source_backend='auto' with no ffmpeg fallback (the fallback block was later removed in refactor). A cold on-demand source the remuxer can't serve (fMP4/encrypted/not-yet-connected) then produces no HLS and never opens; an already-live stream skips the start path. Gate the unsupervised native launch on `fanout_source_backend === 'native'` (explicit opt-in) so `auto` stays on ffmpeg off-fanout, exactly as in 2.6.6. The daemon (fanout on, supervised) still supplies auto's own ffmpeg fallback and is unchanged. 2. Created channels stay at 0% on a cluster mode-2 (api) LB. PR #384's new vod:<id> resolution (StreamProcess::resolveVodSource) and created-channel EPG (CreatedChannelEpg::regenerate → reservedSourceId) queried MySQL directly, which a mode-2 node refuses (LbDatabaseAccessException). Read the VOD's container/status through StreamSource (replica + runtime store, as the rest of the build already does), and no-op the EPG regen on a mode-2 node (ReplicaBoot::apiMode) — MAIN's daily EPG cron regenerates every type-3 channel from the cc_info/stream_started the node syncs back. Full Unit suite green (5319 tests). The mode-2 and native-remux paths still want the live-node acceptance that was skipped for #380/#384. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AneTzAHPPkYWPQjwyZ2td9
50 lines
1.7 KiB
PHP
50 lines
1.7 KiB
PHP
<?php
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use XcVm\Domain\Stream\StreamProcess;
|
|
use XcVm\Infrastructure\Database\DatabaseFactory;
|
|
|
|
final class CreatedChannelSourceTest extends TestCase {
|
|
private TestDb $rDb;
|
|
|
|
protected function setUp(): void {
|
|
if (!defined('SERVER_ID')) {
|
|
define('SERVER_ID', 1);
|
|
}
|
|
$this->rDb = new TestDb();
|
|
$this->rDb->exec('CREATE TABLE `streams` (`id` INT PRIMARY KEY, `type` INT, `target_container` VARCHAR(16), `direct_source` INT DEFAULT 0)');
|
|
$this->rDb->exec('CREATE TABLE `streams_servers` (`stream_id` INT, `server_id` INT, `stream_status` INT, `to_analyze` INT)');
|
|
$this->rDb->query("INSERT INTO `streams` VALUES (7, 2, 'mp4', 0)");
|
|
$this->rDb->query('INSERT INTO `streams_servers` VALUES (7, 1, 0, 0)');
|
|
DatabaseFactory::set($this->rDb);
|
|
}
|
|
|
|
protected function tearDown(): void {
|
|
DatabaseFactory::reset();
|
|
}
|
|
|
|
private function resolve(string $e, int $s = 1): ?string {
|
|
$m = new \ReflectionMethod(StreamProcess::class, 'resolveVodSource');
|
|
$m->setAccessible(true);
|
|
return $m->invoke(null, $e, $s);
|
|
}
|
|
|
|
public function testVodEntryResolvesToEncodedFile(): void {
|
|
$this->assertSame(VOD_PATH . '7.mp4', $this->resolve('vod:7'));
|
|
}
|
|
|
|
public function testVodEntryMissingOnServerReturnsNull(): void {
|
|
$this->assertNull($this->resolve('vod:7', 2));
|
|
}
|
|
|
|
public function testVodEntryBrokenReturnsNull(): void {
|
|
$this->rDb->query('UPDATE `streams_servers` SET `stream_status` = 1 WHERE `stream_id` = 7');
|
|
$this->assertNull($this->resolve('vod:7'));
|
|
}
|
|
|
|
public function testVodEntryStillAnalysingReturnsNull(): void {
|
|
$this->rDb->query('UPDATE `streams_servers` SET `to_analyze` = 1 WHERE `stream_id` = 7');
|
|
$this->assertNull($this->resolve('vod:7'));
|
|
}
|
|
}
|