Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
"speedscope-parser-report-link-text": "View",
"speedscope-editpage-profile-preview-label": "Generate flamegraph",
"speedscope-editpage-profile-preview-title": "Generate a speedscope flamegraph for the preview.",
"speedscope-editpage-profile-notice": "A speedscope profile for this preview can be viewed [$1 here]."
"speedscope-editpage-profile-notice": "A speedscope profile for this preview can be viewed [$1 here].",
"speedscope-profile-name-preview": "Preview of $1"
}
3 changes: 2 additions & 1 deletion i18n/qqq.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
"speedscope-parser-report-link-text": "Text of the link in the parser report that leads to the speedscope profile viewer.",
"speedscope-editpage-profile-preview-label": "Label of the checkbox that can be ticked to generate a speedscope flamegraph for the preview.",
"speedscope-editpage-profile-preview-title": "Title of the checkbox that can be ticked to generate a speedscope flamegraph for the preview.",
"speedscope-editpage-profile-notice": "Notice displayed when profiling a preview. $1 the URL for the profile viewer for the profile."
"speedscope-editpage-profile-notice": "Notice displayed when profiling a preview. $1 the URL for the profile viewer for the profile.",
"speedscope-profile-name-preview": "Name of profiles that were forced for previews through the preference.\n\nParameters:\n* $1 - The name of the page that's being previewed"
}
4 changes: 4 additions & 0 deletions src/HookHandlers/ProfilePreviewsHooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ public function onParserBeforeInternalParse( $parser, &$text, $stripState ): voi
);
if ( !$this->profiler->getProfile() ) {
$this->profiler->recordProfile( SpeedscopeProfile::CAUSE_FORCED_PREVIEW, $id );
$this->profiler->getProfile()?->setName( $parser->msg(
'speedscope-profile-name-preview',
(string)$parser->getPage(),
)->text() );
// @codeCoverageIgnoreStart
if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
ProfileHooks::sendProfileHeader();
Expand Down
8 changes: 4 additions & 4 deletions src/SpeedscopeLogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function log( SpeedscopeProfile $profile ): StatusValue {
}

$requestUri = $_SERVER['REQUEST_URI'] ?? MW_ENTRY_POINT;
$data = $this->appendAdditionalData( $data, $requestUri );
$data = $this->appendAdditionalData( $data, $profile->getName() ?? $requestUri );

$context = RequestContext::getMain();
$body = json_encode( [
Expand Down Expand Up @@ -92,11 +92,11 @@ public function log( SpeedscopeProfile $profile ): StatusValue {
/**
* Add some additional data to the profile.
* @param array<string, mixed> $data
* @param string $requestUri
* @param string $profileName
* @return array<string, mixed>
*/
private function appendAdditionalData( array $data, string $requestUri ): array {
$data['profiles'][0]['name'] = $requestUri;
private function appendAdditionalData( array $data, string $profileName ): array {
$data['profiles'][0]['name'] = $profileName;
if ( $this->options->get( SpeedscopeConfigNames::EXPOSE_CPU_INFO ) ) {
$data['cpuinfo'] = file_get_contents( '/proc/stat' );
}
Expand Down
18 changes: 17 additions & 1 deletion src/SpeedscopeProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ class SpeedscopeProfile {
private ?array $data = null;
/** @see ParserOutput::getLimitReportJSData() */
private ?array $parserReport = null;
/** @var bool Whether we should store the parser output for the current request */
/** Whether we should store the parser output for the current request */
private bool $storeParserReport = false;
/** The name of the profile. If null, the request URL will be used instead. */
private ?string $name = null;

/**
* @param string $environment The environment of the request, e.g. `prod` or `dev`
Expand Down Expand Up @@ -114,4 +116,18 @@ public function shouldStoreParserReport(): bool {
return $this->storeParserReport;
}

/**
* @return string|null The name of the profile, or null if none was set.
*/
public function getName(): ?string {
return $this->name;
}

/**
* @param string|null $name The name of the profile, or null to use the request URL.
*/
public function setName( ?string $name ): void {
$this->name = $name;
}

}
9 changes: 8 additions & 1 deletion tests/phpunit/unit/ProfilePreviewsHooksUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use MediaWiki\Extension\Speedscope\Profiler\ISpeedscopeProfiler;
use MediaWiki\Extension\Speedscope\SpeedscopeConfigNames;
use MediaWiki\Extension\Speedscope\SpeedscopeProfile;
use MediaWiki\Message\Message;
use MediaWiki\Page\PageIdentityValue;
use MediaWiki\Parser\Parser;
use MediaWiki\Parser\ParserOptions;
use MediaWiki\Parser\ParserOutput;
Expand Down Expand Up @@ -77,7 +79,10 @@ public function testOnParserBeforeInternalParse_OptionDisabled() {

public function testOnParserBeforeInternalParse_Success() {
RequestContext::getMain()->getRequest()->setVal( 'wpProfilePreview', true );
$parser = $this->createNoOpMock( Parser::class, [ 'getOptions', 'getOutput', 'getUserIdentity' ] );
$parser = $this->createNoOpMock(
Parser::class,
[ 'getOptions', 'getOutput', 'getPage', 'getUserIdentity', 'msg' ]
);
$parserOptions = $this->createMock( ParserOptions::class );
$parserOptions->expects( $this->once() )->method( 'getRenderReason' )->willReturn( 'page-preview' );
$parser->method( 'getOptions' )->willReturn( $parserOptions );
Expand All @@ -93,7 +98,9 @@ public function testOnParserBeforeInternalParse_Success() {
->with( ProfilePreviewsHooks::EXTENSION_DATA_KEY, true );
$parser->expects( $this->atLeastOnce() )->method( 'getOutput' )->willReturn( $parserOutput );
$user = $this->createNoOpMock( User::class );
$parser->method( 'getPage' )->willReturn( PageIdentityValue::localReference( 0, __METHOD__ ) );
$parser->expects( $this->atLeastOnce() )->method( 'getUserIdentity' )->willReturn( $user );
$parser->method( 'msg' )->willReturn( $this->createMock( Message::class ) );

$text = '';
$createdProfile = false;
Expand Down
Loading