{"record":{"id":"1dcec2ce4f91e2d8","repo":"sebastianbergmann/phpunit","slug":"getrusage-did-not-return-the-expected-keys-s","errorCode":null,"errorMessage":"getrusage() did not return the expected keys \"%s\" and \"%s\".","messagePattern":"getrusage\\(\\) did not return the expected keys \"(.+?)\" and \"(.+?)\"\\.","errorType":"exception","errorClass":"PHPUnit\\Event\\RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Event/Value/Telemetry/SystemCpuTimeMeter.php","lineNumber":58,"sourceCode":"    /**\n     * @param 'ru_stime.tv_sec'|'ru_utime.tv_sec'   $secondsKey\n     * @param 'ru_stime.tv_usec'|'ru_utime.tv_usec' $microsecondsKey\n     *\n     * @throws RuntimeException\n     */\n    private function cpuTime(string $secondsKey, string $microsecondsKey): CpuTime\n    {\n        $usage = getrusage();\n\n        if ($usage === false) {\n            // @codeCoverageIgnoreStart\n            throw new RuntimeException('getrusage() failed.');\n            // @codeCoverageIgnoreEnd\n        }\n\n        if (!isset($usage[$secondsKey]) || !isset($usage[$microsecondsKey])) {\n            // @codeCoverageIgnoreStart\n            throw new RuntimeException(\n                sprintf(\n                    'getrusage() did not return the expected keys \"%s\" and \"%s\".',\n                    $secondsKey,\n                    $microsecondsKey,\n                ),\n            );\n            // @codeCoverageIgnoreEnd\n        }\n\n        $seconds      = $usage[$secondsKey];\n        $microseconds = $usage[$microsecondsKey];\n\n        if (!is_int($seconds) || !is_int($microseconds)) {\n            // @codeCoverageIgnoreStart\n            throw new RuntimeException(\n                sprintf(\n                    'getrusage() returned non-integer values for \"%s\" and/or \"%s\".',\n                    $secondsKey,","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Event/Value/Telemetry/SystemCpuTimeMeter.php#L40-L76","documentation":"After a successful getrusage(), SystemCpuTimeMeter expects the POSIX keys 'ru_utime.tv_sec'/'ru_utime.tv_usec' (or 'ru_stime.*') in the returned array. If either key is missing, it throws this RuntimeException. Like the other getrusage guards it is @codeCoverageIgnore'd because real PHP always returns those keys; only a non-standard or intercepted getrusage() returning a different array shape can trigger it.","triggerScenarios":"A shadowed/mocked getrusage() (namespace 'use function' trick, uopz, runkit7) returning a partial or renamed array; platform abstractions or patched PHP builds that alter the rusage array structure.","commonSituations":"Unit tests of telemetry code with hand-rolled getrusage stubs; exotic SAPIs; debugging sessions where a debugger extension rewrites native function results.","solutions":["Inspect what getrusage() actually returns in that environment: php -r 'var_dump(array_keys(getrusage()));' and compare against ru_utime.tv_sec/ru_utime.tv_usec/ru_stime.*.","Fix or remove the function override so the stock array shape is preserved.","Catch PHPUnit\\Event\\RuntimeException around the meter calls and skip CPU-time reporting when the environment is known to be constrained."],"exampleFix":"// stub fix: return the POSIX shape\n// before\nfunction getrusage(): array { return ['utime_sec' => 1, 'utime_usec' => 500]; }\n\n// after\nfunction getrusage(): array { return ['ru_utime.tv_sec' => 1, 'ru_utime.tv_usec' => 500, 'ru_stime.tv_sec' => 0, 'ru_stime.tv_usec' => 0]; }","handlingStrategy":"fallback","validationCode":"$usage = getrusage();\nif ($usage === false || !isset($usage['ru_utime.tv_sec'], $usage['ru_utime.tv_usec'])) {\n    // rusage array shape unsupported here; skip CPU-time telemetry\n}","typeGuard":null,"tryCatchPattern":"try {\n    $cpu = $meter->userCpuTime();\n} catch (PHPUnit\\Event\\RuntimeException $e) {\n    // Unexpected getrusage() shape: degrade to time-only reporting\n}","preventionTips":["Make any getrusage() test double return the full POSIX key set (ru_utime.tv_sec, ru_utime.tv_usec, ru_stime.tv_sec, ru_stime.tv_usec).","Verify the rusage array shape when PHP or SAPI changes.","Treat CPU telemetry as optional and guard it in environment-portable runners."],"tags":["phpunit","telemetry","getrusage","environment","php"],"backgroundTag":"system-call-failed","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}