markTestSkipped('Symlink creation is not permitted in this environment.'); } try { /* GLOB_MARK supplies this trailing slash for directory symlinks. */ install_rmdir_recursive($root . '/internal-link/', true); install_rmdir_recursive($root . '/external-link', true); expect(file_exists($root . '/internal-link'))->toBeFalse() ->and(file_exists($root . '/target/keep.txt'))->toBeTrue() ->and(file_exists($root . '/external-link'))->toBeFalse() ->and(file_exists($external . '/keep.txt'))->toBeTrue(); } finally { @unlink($root . '/internal-link'); @unlink($root . '/external-link'); @unlink($root . '/target/keep.txt'); @rmdir($root . '/target'); @rmdir($root); @unlink($external . '/keep.txt'); @rmdir($external); } }); test('installer cleanup rejects regular files outside the Cacti tree', function () { $outside = sys_get_temp_dir() . '/cacti-installer-outside-' . bin2hex(random_bytes(8)); file_put_contents($outside, 'keep'); try { install_unlink($outside); expect(file_get_contents($outside))->toBe('keep'); } finally { @unlink($outside); } });