KCacheGrind Source Code Annotation on WAMP


KCacheGrind is awesome.  But the source code annotation (the “source code” tab) doesn’t work when the profile originated on a WAMP installation. When you take a profile on Windows, the header of the file looks like this:

version: 1
creator: xdebug 2.1.2
cmd: C:\wamp\www\wordpress\wp-admin\index.php
part: 1
positions: line

And all of the file lines contain similar paths (C:\wamp\www\....\functions.php).

The backslashes seem to confuse KCacheGrind’s path resolution. The simple fix was to convert the backslashes to forward slashes. I did this with sed via cygwin:

sed -i 's/\\/\//g' cachegrind.out.*

You could probably achieve similar results with TextPad or GrepWin, though.

After that, all of the source code annotation worked. If it doesn’t work for you, try adding your source folder under KCacheGrind -> Settings -> Source Annotation.

Advertisements

PHPUnit: process isolation and “constant already defined”


This weekend, some WordPress core devs ported the unit tests over to a new phpunit compatible runner. I was very excited about this, particularly because the tests I maintain define a constant (DOING_AJAX) which can impact other tests.  Using process isolation should remove this impact, although at a performance cost.  I used the @runTestsInSeparateProcesses annotation, but the tests failed.  PHPUnit was restoring the global state (e.g. before the test split into a separate process) and it looked like this:

1.) Define all of the constants that were already defined
2.) Include the included files

This is the wrong process for the WordPress framework though. The included files were responsible for defining the constants. When they are included, they generate notices for defining constants that are already defined (by PHPUnit).

We all put our heads together and came up with a fix (props nacin) by hijacking PHPUnit_Framework_TestCase::prepareTemplate().

class MyTestCase extends PHPUnit_Framework_TestCase {

	/**
	 * Define constants after requires/includes
	 * @param Text_Template $template
	 * @return void
	 */
	public function prepareTemplate( Text_Template $template ) {
		$template->setVar( array(
			'constants'    => '',
			'zz_constants' => PHPUnit_Util_GlobalState::getConstantsAsString()
		));
		parent::prepareTemplate( $template );
	}
}

Yes, this is hacky, and PHPUnit warns that prepareTemplate() was deprecated in 3.4.0. But when we looked, there were no other solutions, except disabling process isolation.