April 21, 2012

Debugging PHP CLI scripts and phpunit unit tests in Eclipse with XDebug

Nowadays I've spent some time at stackoverflow.com, mostly because I wanted to give back something in exchange for the many solutions found there in the last few years. Browsing the questions found an interesting one asking if it was possible to debug unit tests.
Maybe another post will be about how to install phpunit with PEAR, but let's assume you already have it installed. As of writing this post, the actual Eclipse version is Indigo 3.7.2 with PDT 3.0.0.
You will need XDebug, if you use debian or ubuntu, the package is called php5-xdebug.
Without going into the details - because a couple other guys have already done that, just google 'eclipse xdebug' - I'd like to point out some important things. First, make sure you have everything installed and set up, you can follow instructions described in this document.

So, here come the important bits:

- You must have a phpunit.php in your project to debug unit tests. In ubuntu, you can copy /usr/bin/phpunit to your-project/some-dir/phpunit.php

- Add the PEAR directory as a PHP user library to Eclipse (Preferences / PHP / PHP Libraries), and add this library to the include path of your projects (Project Properties / PHP Include Path / Libraries).

- Eclipse - and PDT - runs PHP executable with a custom php.ini file, and the -n command line switch, so you have to create a full php.ini containing all the .ini files from the conf.d directory. The best way to realize this is to notice that your extensions are not loaded when running scripts within Eclipse, or you see that the debugger does not stop on breakpoints, because the xdebug extension is not loaded either.
Create a directory somewhere and concatenate all the .ini files together. You can do it running a command like this:
cat /etc/php5/cli/php.ini /etc/php5/cli/conf.d/* > /usr/local/etc/php5/php.ini
Set up the PHP executable in Eclipse (Preferences / PHP / PHP Executables), and specify this php.ini file location. After this, exit Eclipse and start it up with the -clean option.

- Make sure that your bootstrap.php file is set up to be run from anywhere, even from another working directory. Avoid including files like require_once('../classes/someclass.php'); use absolute paths instead, or start from the bootstrap.php file's directory to build absolute paths.

- Open a unit test file in Eclipse, and click Debug Configurations from the Run menu. Create a PHP CLI Application configuration. Select the PHP runtime you've just set up, and specify your phpunit.php file's as the 'PHP File', use relative path from your workspace directory, or just use Browse. Also, it may come handy to set the 'Break at first line' to on.
Go to PHP Script Arguments tab, and set command line options for phpunit you want to use (A 2 cent tip: don't use '--colors' in Eclipse) and the unit test's file name you want to debug. Usually the arguments would include
--configuration '/path/to/your/phpunit.xml'
or
--bootstrap '/path/to/your/bootstrap.php'
You can use the variables defined to avoid setting full paths here:
--configuration "${workspace_loc}/my-project/test/phpunit.xml" "${resource_loc}"
The '${resource_loc}' is a full path to the file you're currently debugging.

When you're done, just click Apply then Debug, and start debugging.

March 29, 2012

A tip for using Doxygen for PHP code

In the last few days I've spent some time researching for a documentation tool for my PHP sources, and after running a couple of circles, I've ended up using Doxygen.
It had some issues though, especially referring to namespaces in the docblock comments, because the docblock syntax allows using backslashes for commands, e.g. \param instead of @param.
I really don't understand why PHP's developers decided to use backslashes as separators for namespaces, but that's a different story.
So, if you use namespaces in docblock comments, you have to escape backslashes, but I didn't want to do that in my code, so I've created an input filter for Doxygen in PHP which does that for me.
It also appends variable names to @var type declarations, so e.g.
/**
 * @var string
 */
public $name;

becomes
/**
 * @var string $name
 */
public $name;

which would be redundant in your code, but Doxygen seems to prefer this format.

I've added the filter to a Bitbucket repository, find it here:
https://bitbucket.org/tamasimrei/misc-tools/src/master/doxygen/filter.php

Licensed under the MIT License.

See the Doxygen documentation on how to use an input filter, but basically it's just adding a line like this to your Doxyfile config file:
INPUT_FILTER = /home/tom/misc-tools/doxygen/filter.php

Comments are welcome.

March 20, 2012

Find files with Windows line endings

Just a quickie with some bash magic... I wanted to eliminate mixed and windows line endings from my source files, and after some research and development I got this command line:

find . -not -name *.svn-base -exec grep -Ils $'\r$' {} \;

You must love bash and all of these amazing you-can-do-anything commands. Just takes some time to learn them, and to be able to use them without heavy googling.

March 19, 2012

The mystery of slow XML loading - solved

Last week I've spent some time installing a VMWare hosted linux server onto my Windows 7 PC in the office, mostly because our development server is under a heavy load for several things, e.g. a Jenkins CI instance.
After some experimenting with Debian stable (squeeze) and testing (wheezy), I've ended up using Ubuntu Server 10.04 LTS, long story short because of the support from VMWare, and the available 2.6.x kernel (had network issues with the 3.2.x kernel).
It worked as a charm, installing the whole thing together with Apache, PHP5 and the required PHP modules didn't take more than 30 minutes, the testing phpinfo() page jumped into my browser like a squirrel on red bull.

I've checked out the source of one of our projects, stoked to see how it'd work with my VM. Set up virtual host, done. Configure app, done. Let's open it in a browser. Surprise! One page load took about 2 minutes. WTF?!?
OK, let's see CPU load on the VM. None.
OK, it must be HDD load then. None.
OK -I'm not giving up- the network is slow again. No.
OK, the VM apache is waiting for the response from database server. No.
OK, then what the fudge is happening? Let's run some benchmarks. Phpinfo page is loading like in no time.
OK, so it must be something with our stuff, but what? At this point I remembered that back in the old days I had a story with configuring the Exim MTA, and it had a network wait timeout...
OK, let's see what's happening on the network. After starting up iptraf, I've noticed that there's an external IP which is connected to the VM. The IP address is pointing to a w3c.org host, let's google that. And voila! after a few minutes I've learned that the PHP DOM extension is set to load the DTD for loading and parsing XML files... Our app has a setting to disable DTD loading, but I didn't like that idea, and a comment on a PHP documentation page said that the DTD's can be stored locally. At this point - 8.30PM, still in the office, feeling like a zombie - I've asked our lead developer - who was also still in the office :) - how can I have solve this thing. He pointed me to a package called w3c-dtd-xhtml holding the DTD's. After installing it, our app was running like crazy, no waiting, I could even copy the database from the dev server, and run it locally, it's still fast enough.

Today I've installed Apache on the Windows host, and set it up to reverse proxy the VM out for the others in the office, and it runs smoothly.

How could I be that stupid to say Windows when I was asked what OS I'd like to use on my PC, when almost everything I use for development is available on linux now...
... not that I wouldn't have the same issue on a linux desktop tho :)

March 3, 2012

Fix Spotify install in Ubuntu 11.10

In the last couple of weeks, I've been using Spotify to listen to music during work, and more and more at home. Unfortunately, it seems like the developers at Spotify prefer to develop for Windows, the Windows client in the office just runs without problems, and it's regularly updated.

The "Linux Preview" version is first of all a bit tricky to install, and doesn't seem to be updated in a while.  (Plus, it's not too smart that I - living in the Netherlands - cannot change the language of the page to English, if I choose the Netherlands under the 'Land' menu, I must read the whole page in Dutch.)

So, for some songs and albums I've got an error message saying

"There is a problem with the sound decoder. Spotify can't play music"

After checking everything I could with my sound settings - I own a Logitech Cooling pad with built-in speakers for my notebook, that caused me some difficulties to install under Ubuntu, but that's another story - I've found that the spotify-client-qt package depends on the libavcodec52 (3) and libavformat52 (4) packages which seem to be missing.

With some googling, I've found (1,2) that I'm - of course - not alone with this issue, and the missing packages are from an earlier version of Ubuntu. Not that I don't trust other people posting files to download services for patching your system (I don't, and you shouldn't either), downloaded the two mentioned packages from the 'local' ubuntu repository, and a third one: libavutil50 (5) because of dependency.

Installed them in the following order - and commands:

dpkg -i libavutil50_0.6.4-0ubuntu0.11.04.1_amd64.deb
dpkg -i libavcodec52_0.6.4-0ubuntu0.11.04.1_amd64.deb
dpkg -i libavformat52_0.6.4-0ubuntu0.11.04.1_amd64.deb

... and finally I can listen to Peter Gabriel songs in Spotify!

Note that I'm using 64bit Ubuntu, so if you use 32bit, you have to download and install the *_i386.deb packages.

Thanks for the authors of the original posts!

Links:

  1. https://getsatisfaction.com/spotify/topics/ubuntu_lucid_spotify_linux_preview_local_files_problem_with_sound_decoder
  2. http://www.webupd8.org/2011/12/how-to-install-native-spotify-linux.html
  3. http://nl.archive.ubuntu.com/ubuntu/pool/main/liba/libav/libavcodec52_0.6.4-0ubuntu0.11.04.1_amd64.deb
  4. http://nl.archive.ubuntu.com/ubuntu/pool/main/liba/libav/libavformat52_0.6.4-0ubuntu0.11.04.1_amd64.deb
  5. http://nl.archive.ubuntu.com/ubuntu/pool/main/liba/libav/libavutil50_0.6.4-0ubuntu0.11.04.1_amd64.deb


February 24, 2012

Install Oracle Java 7 in Ubuntu 11.10

It may be just me, but I wanted to be sure I'm running the latest, "bestest" Java version available, so decided to switch from the default install of OpenJDK 6 to Oracle's Java 7 JDK version.
Google is my friend, Wiki(pedia) is my girlfriend, found this post with detailed installation instructions:

http://www.twm-kd.com/linux/install-oracle-java-sdk-in-ubuntu-11-10/

After following the steps in that post carefully, you can test if you're running the intended version by visiting this page:

http://javatester.org/version.html

If you'd like to update your installation, just download the updated JDK (in my case it was the JDK 7 x64), rename the old /usr/lib/jvm/java-7-oracle to something else, unpack/rename the downloaded JDK, and there you go. Make sure you're not running any java programs or browser plugins before the update.

Thanks for the good guys at Three Wise Men!

February 18, 2012

OpenLDAP after upgrading debian


Long story short: my friend upgraded his debian server, and asked me to help him upgrading OpenLDAP (slapd), because it didn't start. Not that I was a big expert of slapd - on the contrary - but I was the one who configured it for the first time, maybe I could make it fly again.

Started restarting slapd (/etc/init.d/slapd restart), no success. Let's read the logs. Syslog entry:

bdb(dc=future,dc=neologik,dc=hu): Program version 4.8 doesn't match environment version 0.66

OK, let's Google. Found a couple of posts of I need to upgrade the database (quite funny, the "environment version" refers to the database version, duh?), but all the dbX.X_upgrade tools said the same as slapd, about the not matching versions.

OK, let's Google, round 2. Finally found a post(1) talking about bumping into the same issues, and found no other solution than re-importing the LDAP data from an .ldif file. Fortunately, the good guys at debian made the upgrade script so it creates a backup .ldif file in /var/backups.

So, I've purged slapd to have a clean start, reconfigured the domain and the admin password (not going into the details, if you are reading this post, you know how to install/purge a package in debian ;) and tried to run:
ldapadd -h localhost -x -W -D "cn=admin,dc=example,dc=com" -c -f backup.ldif

Asked me for the admin password, gave it, then it said a couple times:

adding new entry "dc=host,dc=example,dc=com"
ldap_add: Constraint violation (19)
additional info: structuralObjectClass: no user modification allowed

What the heck? OK, Google.... finally found a post(2) explaining that certain entries must be removed from the ldif file before import. Thanks to the poster, there's even a command provided I didn't have to spend time with search & replace:

$ cat > ldapadd.sed <<EOF
/^creatorsName:/d
/^createTimestamp:/d
/^modifiersName:/d
/^modifyTimestamp:/d
/^structuralObjectClass:/d
/^entryUUID:/d
/^entryCSN:/d
EOF

$ cat backup.ldif | sed -f ldapadd.sed > bacon.ldif

After this, running ldapadd with bacon.ldif instead of backup.ldif did the trick and imported all the entries into LDAP.

ldapadd -h localhost -x -W -D "cn=admin,dc=example,dc=com" -c -f bacon.ldif

Thanks to the authors of the original posts, and the authors of debian and OpenLDAP.


Links:


February 1, 2012

Configure Ipredator VPN in Ubuntu 11.10

Without going into the details - it's pretty self explanatory how you should add a VPN connection - I'd like to note a required setting, which is not really documented anywhere:
When you've added the connection, entered your username and password, click Advanced, and check Use Point-to-Point Encryption (MPPE) on under Security and Compression.
Withouth this setting on you may get entries in your syslog like:
- LCP terminated by peer - MPPE required but peer negotiation failed

With this, the Ipredator VPN works like a charm.

Ipredator: http://www.ipredator.se/

January 31, 2012

Fonts in Eclipse Project Explorer

First of all thanks to all the developers of Eclipse and related projects, I've been using it for years now, it's hard to imagine working on a software project without it.
In the previous post, I've described how I created a desktop shortcut for Eclipse. After successfully running it I've found the font used in the Project Explorer looking beautiful, but way too big.
Here's a couple possible solutions - I've successfully tested overwriting the theme settings for Eclipse:

http://techtavern.wordpress.com/2008/09/24/smaller-font-sizes-for-eclipse-on-linux/

January 30, 2012

Desktop Icons in Ubuntu 11.10

Here's a good one:
I wanted to create an application 'Shortcut' on my desktop to fire up Eclipse.
Coming from the (shame on me) m$ windows desktop world, I couldn't figure it out how, then after some google search, found this article, and guess what, it works :)

http://www.ubuntugeek.com/how-to-create-desktop-launchers-in-ubuntu-11-10oneiric.html