Archive for the ‘PHP’ Category

Simpletest and brittle test cases

Wednesday, March 19th, 2008

I’ve been thoroughly annoyed the last 2 days with Simpletest.

The mock objects have some unexpected behaviour when setting return values for their methods:

$someMock->setReturnValue('get', 123);
$someMock->setReturnValue('get', 234);

Which value does it use? 123. It doesn’t overwrite the first set value. How do we get around this problem? Like this:

$someMock->setReturnValueAt(0, 'get', 123);
$someMock->setReturnValueAt(1, 'get', 234);

setReturnValueAt() allows you to specifiy return values for any additional calls to that method. This is all dandy, but its making my test cases very brittle by creating a tight coupling between my test case and the code being tested.

What I want to be able to do is:

1) set the return value for the mock object
2) run the test that calls this method, not caring how many times the method is called (for argument sake, lets say this is a simple getter method).
3) set the return value for the mock object to something else
4) run another test

I don’t see any way of doing this other that creating a new instance of the mock object. O well.

Wireshark

Wednesday, November 14th, 2007

I installed Wireshark out of curiosity - I’d seen it mentioned and wanted to see how I could find a use for the network protocol analyzer. It sat lying around until a friend asked whether or not it would be possible to skew a particular poll result.

The poll used a flash frontend. I knew there had to be backend it communicated with, so I fired up Wireshark, started logging and cast my vote. A simple ping to the web host revealed the IP address of the destination host which I used to sort the Wireshark result set. There it was - a post to a PHP script to record my vote, complete with HTTP headers and URL string.

Thanks to the Zend Framework and a few lines of code later, my very own poll skewer:

<?php

require_once(’C:/php/libs/Zend/Http/Client.php’);

$client = new Zend_Http_Client(’http://www.somedomain.com/poll/poll.php’);
$client->setParameterPost(’pollId’, ‘7654′);
$client->setParameterPost(’answerId’, ‘3′);

$response = $client->request(’POST’);
print urldecode($response->getBody());

?>

Throw that in a loop and iterate a few thousand times and you quickly begin to understand how important it is to add restrictions based on a user’s IP address and / or cookies - even though these often cause more trouble than they’re worth.

In a PECL - Subversion API for PHP

Friday, August 24th, 2007

The PECL SVN extension provides bindings for the SNV API. Its currently in version 0.2 Beta (and there doesn’t seem to be all that much activity on the project), but I have successfully tested some of the basic methods (checkout, ls, add, commit) without problems. There is, however, no documentation on the functions provided by the extension, so I dug through the extension code to make a list of the available functions:

bool svn_checkout(string repos, string targetpath [, int revision])
Checks out a particular revision from repos into targetpath

mixed svn_diff(string path1, int rev1, string path2, int rev2)
Recursively diffs two paths. Returns an array consisting of two streams: the first is the diff output and the second contains error stream output

bool svn_cleanup(string workingdir)
Recursively cleanup a working copy directory, finishing any incomplete operations, removing lockfiles, etc.

string svn_fs_revision_prop(resource fs, int revnum, string propname)
Fetches the value of a named property

resource svn_fs_youngest_rev(resource fs)
Returns the number of the youngest revision in the filesystem

resource svn_fs_revision_root(resource fs, int revnum)
Get a handle on a specific version of the repository root

resource svn_fs_file_contents(resource fsroot, string path)
Returns a stream to access the contents of a file from a given version of the fs

int svn_fs_file_length(resource fsroot, string path)
Returns the length of a file from a given version of the fs

long svn_fs_node_prop(resource fsroot, string path, string propname)
Returns the value of a property for a node

long svn_fs_node_created_rev(resource fsroot, string path)
Returns the revision in which path under fsroot was created

array svn_fs_dir_entries(resource fsroot, string path)
Enumerates the directory entries under path; returns a hash of dir names to file type

int svn_fs_check_path(resource fsroot, string path)
Determines what kind of item lives at path in a given repository fsroot

resource svn_repos_fs(resource repos)
Gets a handle on the filesystem for a repository

resource svn_repos_open(string path)
Open a shared lock on a repository.

resource svn_repos_create(string path [, array config [, array fsconfig]])
Create a new subversion repository at path

bool svn_repos_recover(string path)
Run recovery procedures on the repository located at path.

bool svn_repos_hotcopy(string repospath, string destpath, bool cleanlogs)
Make a hot-copy of the repos at repospath; copy it to destpath

array svn_commit(string log, array targets [, bool dontrecurse])
Make a hot-copy of the repos at repospath; copy it to destpath

array svn_add(string path [, bool recursive [, bool force]])
Schedule the addition of a file in a working directory

array svn_status(string path [, bool recursive [, bool get_all [, bool update [, bool no_ignore]]]])
Schedule the addition of a file in a working directory

array svn_update(string path [, int revno [, bool recurse]])
Update working copy at path to revno

resource svn_repos_fs_begin_txn_for_commit(resource repos, long rev, string author, string log_msg)
create a new transaction

long svn_repos_fs_commit_txn(resource txn)
commits a transaction and returns the new revision

resource svn_fs_txn_root(resource txn)
creates and returns a transaction root

boolean svn_fs_make_file(resource root, string path)
creates a new empty file, returns true if all is ok, false otherwise

boolean svn_fs_make_dir(resource root, string path)
creates a new empty directory, returns true if all is ok, false otherwise

resource svn_fs_apply_text(resource root, string path)
creates and returns a stream that will be used to replace the content of an existing file

boolean svn_fs_copy(resource from_root, string from_path, resourse to_root, string to_path)
copies a file or a directory, returns true if all is ok, false otherwise

boolean svn_fs_delete(resource root, string path)
deletes a file or a directory, return true if all is ok, false otherwise

resource svn_fs_begin_txn2(resource repos, long rev)
create a new transaction

boolean svn_fs_is_file(resource root, string path)
return true if the path points to a file, false otherwise

boolean svn_fs_is_dir(resource root, string path)
return true if the path points to a directory, false otherwise

boolean svn_fs_change_node_prop(resource root, string path, string name, string value)
return true if everything is ok, false otherwise

boolean svn_fs_contents_changed(resource root1, string path1, resource root2, string path2)
return true if content is different, false otherwise

boolean svn_fs_props_changed(resource root1, string path1, resource root2, string path2)
return true if props are different, false otherwise

boolean svn_fs_abort_txn(resource txn)
abort a transaction, returns true if everything is ok, false othewise

Links:

  • The Subversion API Docs (The PECL extension calls the functions in this API, so these docs are useful in determining the purpose of a function in the PECL extension. Generally the function names correspond, but the function parameters differ slightly in some cases)