Files
cacti/tests/Helpers/RequestCoverage.php
Thomas VincentandPetr Macek 930b085703 feat(auth): log administrative account actions after confirmed writes (#8360)
* log user action (create, delete, locked, ..)

* change log

* update changelog

* style(auth): apply coding standards to user action logging

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* Audit password changes only after successful account saves

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(auth): sanitize audit fields and confirm account removals

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: cover native account audit state transitions

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: synchronize native coverage fixture dispatch

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(auth): audit only confirmed account persistence

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: measure coverage at the exact PR revision

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: Petr Macek <petr.macek@kostax.cz>
2026-10-14 09:54:14 -04:00

48 lines
1.8 KiB
PHP

<?php
// Copyright (C) 2004-2026 The Cacti Group. GPL-2.0-or-later.
// Loaded only by the disposable E2E image when coverage is explicitly enabled.
$requestCoverageDirectory = getenv('CACTI_PR_RAW_COVERAGE');
if ($requestCoverageDirectory !== false && $requestCoverageDirectory !== '') {
if (!function_exists('xdebug_start_code_coverage')) {
throw new RuntimeException('Request coverage requires Xdebug.');
}
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
register_shutdown_function(static function () use ($requestCoverageDirectory) : void {
$data = xdebug_get_code_coverage();
foreach ($GLOBALS['cacti_fixture_source_map'] ?? [] as $temporary => $original) {
foreach ($data[$temporary] ?? [] as $line => $hits) {
$data[$original][$line] = max($hits, $data[$original][$line] ?? -2);
}
unset($data[$temporary]);
}
$root = realpath(dirname(__DIR__, 2));
$hashes = [];
$htmlSpans = [];
foreach ($data as $file => $lines) {
if (!str_starts_with($file, $root . '/') || str_contains($file, '/vendor/')) {
unset($data[$file]);
continue;
}
$hashes[$file] = hash_file('sha256', $file);
$htmlSpans[$file] = [];
// Zend records a literal HTML output opcode at the end of its block.
foreach (token_get_all(file_get_contents($file)) as $token) {
if (is_array($token) && $token[0] === T_INLINE_HTML) {
$htmlSpans[$file][] = [$token[2], $token[2] + substr_count($token[1], "\n")];
}
}
}
$path = $requestCoverageDirectory . '/' . getmypid() . '-' . bin2hex(random_bytes(8)) . '.json';
if (file_put_contents($path, json_encode(['root' => $root, 'coverage' => $data, 'hashes' => $hashes, 'html_spans' => $htmlSpans], JSON_THROW_ON_ERROR)) === false) {
throw new RuntimeException('Could not preserve request coverage.');
}
});
}