loadXML('0003'); return $dom; } test('RRD dump loader validates execution output and XML', function () { $command = null; $valid = rrdtool_dump_document( "/tmp/device's metrics.rrd", null, static function (string $value) use (&$command) : string { $command = $value; return '0003'; } ); expect($valid)->toBeInstanceOf(DOMDocument::class) ->and($valid->getElementsByTagName('version')->item(0)?->nodeValue)->toBe('0003') ->and($command)->toBe("dump '/tmp/device'\\''s metrics.rrd'") ->and(rrdtool_dump_document('/tmp/file', null, static fn () : bool => false))->toBeFalse() ->and(rrdtool_dump_document('/tmp/file', null, static fn () : string => ''))->toBeFalse() ->and(rrdtool_dump_document('/tmp/file', null, static fn () : string => ''))->toBeFalse(); }); test('RRD restore installs a complete replacement and preserves mode', function () { $directory = rrd_mutation_test_directory(); $file = $directory . '/source.rrd'; file_put_contents($file, 'original'); chmod($file, 0640); $executor = static function (string $command) : string|false { if (!preg_match("/^restore -f '([^']+)' '([^']+)'$/", $command, $matches)) { return false; } return file_put_contents($matches[2], 'replacement') === false ? false : ''; }; try { expect(rrdtool_restore_document(rrd_mutation_test_document(), $file, null, $executor))->toBeTrue() ->and(file_get_contents($file))->toBe('replacement') ->and(fileperms($file) & 0777)->toBe(0640) ->and(glob($directory . '/.cacti-rrd-restore-*'))->toBe([]); } finally { unlink($file); rmdir($directory); } }); test('RRD restore leaves the original intact when execution or rename fails', function () { $directory = rrd_mutation_test_directory(); $file = $directory . '/source.rrd'; file_put_contents($file, 'original'); $failedExecution = static fn () : bool => false; $successfulExecution = static function (string $command) : string|false { if (!preg_match("/^restore -f '([^']+)' '([^']+)'$/", $command, $matches)) { return false; } return file_put_contents($matches[2], 'replacement') === false ? false : ''; }; try { expect(rrdtool_restore_document(rrd_mutation_test_document(), $file, null, $failedExecution))->toBeFalse() ->and(file_get_contents($file))->toBe('original') ->and(rrdtool_restore_document(rrd_mutation_test_document(), $file, null, $successfulExecution, static fn () : bool => false))->toBeFalse() ->and(file_get_contents($file))->toBe('original') ->and(glob($directory . '/.cacti-rrd-restore-*'))->toBe([]); } finally { unlink($file); rmdir($directory); } });