<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ben Waine</title>
	<atom:link href="http://www.ben-waine.co.uk/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ben-waine.co.uk/blog</link>
	<description></description>
	<lastBuildDate>Sat, 25 Feb 2012 15:41:10 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Ibuidings Challenge</title>
		<link>http://www.ben-waine.co.uk/blog/php/ibuidings-challenge.php</link>
		<comments>http://www.ben-waine.co.uk/blog/php/ibuidings-challenge.php#comments</comments>
		<pubDate>Sat, 25 Feb 2012 15:40:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Challenge]]></category>
		<category><![CDATA[Your Mom Jokes]]></category>

		<guid isPermaLink="false">http://www.ben-waine.co.uk/blog/?p=250</guid>
		<description><![CDATA[Ibuildings have recently announced their new coding challenge.
http://www.ibuildings.com/challenge/
In short its to build a custom notifier for Senio&#8217;s new build tool Sismo.
http://sismo.sensiolabs.org/
The criteria are that:
The notifier falls into one of the following categories:

Usefull
Creative
Inspiring

This got me thinking, what would be the worst penalty for a failing build? Who would you least like notified in the event the [...]]]></description>
			<content:encoded><![CDATA[<p>Ibuildings have recently announced their new coding challenge.</p>
<p><a href="http://www.ibuildings.com/challenge/">http://www.ibuildings.com/challenge/</a></p>
<p>In short its to build a custom notifier for Senio&#8217;s new build tool Sismo.</p>
<p><a href="http://sismo.sensiolabs.org/">http://sismo.sensiolabs.org/</a></p>
<p>The criteria are that:</p>
<p>The notifier falls into one of the following categories:</p>
<ul>
<li>Usefull</li>
<li>Creative</li>
<li>Inspiring</li>
</ul>
<p>This got me thinking, what would be the worst penalty for a failing build? Who would you least like notified in the event the build has failed? The Answer:</p>
<p><strong>Your Mum.</strong></p>
<p>My entry to this competition will be a plugin that notifies the offending developers Mother in the event of a build failure. It also provides fellow developers the opportunity to say &#8216;I notified your Mom&#8217;. Gold.</p>
<p>More to follow.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ben-waine.co.uk/blog/php/ibuidings-challenge.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speaking at DPC12</title>
		<link>http://www.ben-waine.co.uk/blog/uncategorized/speaking-at-dpc12.php</link>
		<comments>http://www.ben-waine.co.uk/blog/uncategorized/speaking-at-dpc12.php#comments</comments>
		<pubDate>Fri, 24 Feb 2012 23:14:41 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.ben-waine.co.uk/blog/?p=246</guid>
		<description><![CDATA[I&#8217;m pleased to announce I&#8217;m speaking at DPC12 this year. I&#8217;m giving a tutorial on Thursday 7th June: &#8220;Acceptence and Integration Testing With Behat&#8221;.
Here is the abstract:
Behat is a behaviour driven development framework for PHP. It can be used to write integration and acceptance tests in a language that non developers can understand. In addition [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m pleased to announce I&#8217;m speaking at DPC12 this year. I&#8217;m giving a tutorial on Thursday 7th June: &#8220;Acceptence and Integration Testing With Behat&#8221;.</p>
<p>Here is the abstract:</p>
<blockquote><p>Behat is a behaviour driven development framework for PHP. It can be used to write integration and acceptance tests in a language that non developers can understand. In addition to being a robust and useful testing tool it can help to make the development process more transparent to non developers and other stakeholders.</p>
<p>The workshop gives attendees an introduction to behaviour driven development (BDD) and goes on to show how to use Behat to accomplish BDD&#8217;s goals. The workshop covers writing tests with Gherkin (the human readable test description language), implementing steps (the executable element to the test written in PHP), testing API&#8217;s using Behat and testing UI&#8217;s using Mink: Behat&#8217;s UI testing toolkit.<br />
At the beginning of the session attendees are provided a virtual machine with Behat installed and a small test application based around the DPC conference. Tests will be written for the existing code to showcase Behats features. Later attendees will follow true BDD best practise, defining behaviour first, writing tests and then developing the next simple piece of functionality.</p>
<p>In addition to the practical work some case studies of &#8216;Behat in the Wild&#8217; are shown and some supporting open source projects are demo&#8217;ed. At the end of the session attendees should be able to go away and start using Behat in their own projects.</p>
<p>Note: Attendees should bring a laptop with Oracle&#8217;s Virtual Box installed. <a href="https://www.virtualbox.org/">https://www.virtualbox.org/</a>
</p></blockquote>
<p>I hope you can make it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ben-waine.co.uk/blog/uncategorized/speaking-at-dpc12.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Importance Of Logging</title>
		<link>http://www.ben-waine.co.uk/blog/php/the-importance-of-logging.php</link>
		<comments>http://www.ben-waine.co.uk/blog/php/the-importance-of-logging.php#comments</comments>
		<pubDate>Tue, 10 Jan 2012 23:36:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Best Practise]]></category>
		<category><![CDATA[Logging]]></category>

		<guid isPermaLink="false">http://www.ben-waine.co.uk/blog/?p=238</guid>
		<description><![CDATA[Until recently I had underestimated the value that can be gained by implementing an effective logging strategy. 
The most common benefit to be gained is of course that it makes your application easier to debug. As a developer you have probably tailed an apache error log when trying to debug an issue. This technique is [...]]]></description>
			<content:encoded><![CDATA[<p>Until recently I had underestimated the value that can be gained by implementing an effective logging strategy. </p>
<p>The most common benefit to be gained is of course that it makes your application easier to debug. As a developer you have probably tailed an apache error log when trying to debug an issue. This technique is just as good for debugging your application providing a good log exists. Having a good application log can show you at a glance where errors are occurring in your application, from technical issues like a database connection going away, to unexpected conditions being reached in the business logic, logs are invaluable. </p>
<p>In production logs will be used by first and second line support teams to diagnose live issues. Good descriptive log lines ensure that the right people get &#8216;called in the middle of the night&#8217; to deal with a production issues. Logs help to diagnose the cause of production issues after they have occurred, they are invaluable when trying to establish the root cause of an incident or when trying to produce an issue that you can&#8217;t seem to replicate in your development environment. </p>
<p>Finally logs can be used to log events that occur within your application for monitoring purposes. This technique is called &#8216;evented logging&#8217; . By treating each line in a log file as an event it&#8217;s possible to monitor logs for events in real time. Events could be technical: API calls, database interactions, page requests. More interestingly you can log business events: Purchases, customer interactions or cash deposits. </p>
<p>Using this technique it&#8217;s possible to monitor business events in real time and present them graphically to stake holders. You can see the impact a change on your live platform has on your business metrics. Has a new release dramatically reduced the number of new registrations per minute? This could point to an unexpected problem in the registration process caused by this change. An excellent tool for this (and a subject for it&#8217;s own post) is <a href="http://graphite.wikidot.com/">Graphite</a>. </p>
<p>Bellow is an example of a common logging format used by apache. </p>
<pre>
127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326
</pre>
<p>In this single line we can see lots of useful information: the ip address of the request, the user&#8217;s ID (frank), the date of the request, the request made, the response and the size of the object returned (example credit: <a href="http://en.wikipedia.org/wiki/Common_Log_Format">Wikipedia</a>).This provides all the information required to log individual requests to a server. Every line in the file represents a request and the format is consistent across lines.</p>
<p>Application logging requires slightly different information. Heres a line to demonstrate :</p>
<pre>
URGENT c68f39913f901f3ddf44c707357a7d70  [10/Oct/2000:13:55:36 -0700] "Database connection lost in DB.php Line 4"
DEBUG c68f39913f901f3ddf44c707357a7d70  [10/Oct/2000:13:56:00 -0700] "Making call to fulfilment service"
</pre>
<p>In an application log we are aggregating numerous different pieces of information from multiple simultaneous requests so some additional meta data is required. In these lines we can see a log level, a unique hash identifying which request has generated the log line, the date time and a textual log line. </p>
<p>The log level is required because we may want to adjust which lines are written to the log file. Extensive debug level logging can be expensive to run in production (as each log line is a file operation). A unique hash is required to identify each request because a request may generate multiple log lines and requests are coming in to the application simultaneously. When analysing logs at a later date we may wish to isolate the lines from individual requests. </p>
<p>Ultimately you can decide based on your applications needs the content and format of your logs. The golden rule is it must be absolutely consistent, logs are most useful when they can be parsed at a later to time to yield information.</p>
<p>An evented log may look like this:</p>
<pre>
URGENT c68f39913f901f3ddf44c707357a7d70  [10/Oct/2000:13:55:36 -0700] BUSEVENT.registration "Customer Registration"
DEBUG c68f39913f901f3ddf44c707357a7d70  [10/Oct/2000:13:56:00 -0700] TECHEVENT.APICall.fulfilment "Fulfilment API Called"
</pre>
<p>It has many common attributes to the standard application log line but it also includes an easily parsed &#8216;.&#8217; delimited string determining the type of event that has occurred. The string can easily be parsed and the appropriate event logged on whatever system you are using to display events to your stake holders.</p>
<p>There are many logging libraries you can make use of to make logging easy, they are often components in frameworks but there are also stand alone libraries. Of course it&#8217;s also easy to implement your own logging library, however you may be accused of re-inventing the wheel. </p>
<p>Some popular libraries:</p>
<p><a href="http://framework.zend.com/manual/en/zend.log.html">Zend Log</a> (part of Zend Framework)<br />
<a href="https://github.com/Seldaek/monolog">Mono Log</a> (Stand alone logging library used in Silex and Symfony 2)</p>
<p>That was my quick introduction to logging and why it&#8217;s important. Go forth and log!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ben-waine.co.uk/blog/php/the-importance-of-logging.php/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Integrating Phabric Into Your Behat Dev / Test Cycle</title>
		<link>http://www.ben-waine.co.uk/blog/behat/integrating-phabric-into-your-behat-dev-test-cycle.php</link>
		<comments>http://www.ben-waine.co.uk/blog/behat/integrating-phabric-into-your-behat-dev-test-cycle.php#comments</comments>
		<pubDate>Mon, 02 Jan 2012 18:23:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[behat]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://www.ben-waine.co.uk/blog/?p=223</guid>
		<description><![CDATA[In this post I&#8217;ll look at how to manage the use and maintenance of Phabric within a team of business analysts, testers and developers. Phabric is a dynamic fixture creation tool I created for use with the testing framework Behat.  It allows you to embed fixture creation into your Gherkin feature files and scenarios. [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I&#8217;ll look at how to manage the use and maintenance of Phabric within a team of business analysts, testers and developers. Phabric is a dynamic fixture creation tool I created for use with the testing framework Behat.  It allows you to embed fixture creation into your Gherkin feature files and scenarios. If you havent encountered the tool before please look at the <a href="https://github.com/benwaine/Phabric">Github</a> page for more information. </p>
<p>In a recent conversation with <a href="http://twitter.com/_md">Marcello Duarte</a> we were discussing ways in which Behat and  Phabric could be used by BA&#8217;s and testers to create scenarios that set up the state of a system and then test interactions based on that state. </p>
<p>Marcello&#8217;s main concern was that because Phabric works by mapping database tables to textual tables in Gherkin scenarios it will always be tightly linked to the underlying database implementation. This causes a number of problems:</p>
<p>1. BA&#8217;s and testers shouldn&#8217;t have to have an encyclopaedic knowledge of the database structure. In many companies the test teams are primarily &#8216;black box&#8217; testing a system, they have no knowledge of the implementation within the system just its outputs given set inputs. </p>
<p>2. This approach doesn&#8217;t play well with an emergent design. Phabric assumes an existing database that is mapped via configuration files and is ready to be populated when a test is run. In an ideal world testers and BA&#8217;s should be able write a large body of tests for features before they are implemented by the development team.     </p>
<p>Phabric has a number of features that can be used to mask the complexity of an underlying database implementation and keep the &#8216;Given&#8217; steps of a scenario nice and simple. The following example illustrates this process. </p>
<p>In this example we will use a fictional company who organise events. The companies application has one database table &#8216;Event&#8217;. The event table has eight columns, they are named in an ugly way, some require specific data entry formats (eg MYSQL DateTime) and not all columns are necessary when creating a test event.   </p>
<pre>
Event Table

event_id
event_name
event_start_date
event_end_date
event_in_progress
event_premium
event_location
event_capacity
</pre>
<p>The goal of this exercise is to make it easy for testers to write scenarios that involve populating this table. This can be done using the following Phabric features: changing the column names, using default values for non critical columns and data transforming functions to make input data look friendly.</p>
<p>The following example scenario shows these features in action:</p>
<pre>
Feature: Event page rendering test
         Checks that the various features of the event page render correctly. 

Scenario: Basic Event Is Displayed Correctly.
    Given the following event exists
        | Name              | Start Date | End Date |
        | BDD For Beginners | 12/12/12   | 13/12/12 |
    When I got to the "home" page
    Then I should see the "BDD For Beginners" event
</pre>
<p>We can see here that:<br />
1. Names of columns are changed to something more readable than &#8216;event_start_time&#8217;<br />
2. Not all columns are required. Under the hood default values are used when columns are not included in the Given step.<br />
3. The values for start and end dates are not in the very verbose MySQL date format.</p>
<p><em>Note: Examples of how to acheive this with Phabric are available in the projects README and examples at <a href="https://github.com/benwaine/Phabric">GitHub</a></em></p>
<p>Developers can write the mappings for database tables, including sensible default values, column name transformations and column data transformations. It&#8217;s important that some kind of documentation exists for the test team. This could be an article on a project wiki or a text file in the projects repository. It should include:</p>
<p>1. Friendly names used to refer to data eg Name / event_name<br />
2. Which data is required<br />
3. What format should be used when entering data. eg &#8211; a bit column might be represented by the text &#8216;YES&#8217; / &#8216;NO&#8217;.<br />
4. A couple of examples of sample scenarios. </p>
<p>The additional work required by developers to create (and maintain) this documentation is quickly repaid by a more self sufficient test team capable of producing data driven scenarios independently of the development team. After the initial structure is in place testers can even add additional fields to Gherkin. The test will fail because the field wont map to the database implementation but the developer working on the feature can add to the existing implementation. They should then add this to the documentation. </p>
<p>Taking this idea one step further and looking at the issue of emergent design, is it possible for test teams to drive the development using Gherkin Tables to describe the desired entities in the system? Testers working closely with business analysts (or whomever it is that has the responsibility for creating stories) could define entities in the system up front.</p>
<p>One way of achieving this would be to write Gherkin tables representing the entities as part of the test creation process. When the tests are handed to developers they could then create a schema and Phabric mapping. They then continue to develop the feature as normal against the tests.  Another way would be to produce a list of the required attributes of an entity up front and pass this to the development team ahead of test creation. They would then use this list to create schema and mapping files.</p>
<p>I hope this simple example has gone some way to illustrate how to use Behat and Phabric within an organisation to stream line the process of test creation. You may have noticed that the example conveniently glossed over relational data. Use of relational data requires some additional thought and development and will be the subject of my next blog post in this series. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.ben-waine.co.uk/blog/behat/integrating-phabric-into-your-behat-dev-test-cycle.php/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Behat In A Large Multi Disiplined Team</title>
		<link>http://www.ben-waine.co.uk/blog/behat/using-behat-in-a-large-multi-disiplined-team.php</link>
		<comments>http://www.ben-waine.co.uk/blog/behat/using-behat-in-a-large-multi-disiplined-team.php#comments</comments>
		<pubDate>Sun, 01 Jan 2012 18:09:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[behat]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[BDD]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.ben-waine.co.uk/blog/?p=217</guid>
		<description><![CDATA[Behat is a relatively new testing framework, many developers are using it in personal projects and teams are beginning to use it for production projects as well. Recently a number of people have asked me about how Behat testing is integrated into larger projects involving teams of developers, testers and other stake holders. Common questions [...]]]></description>
			<content:encoded><![CDATA[<p>Behat is a relatively new testing framework, many developers are using it in personal projects and teams are beginning to use it for production projects as well. Recently a number of people have asked me about how Behat testing is integrated into larger projects involving teams of developers, testers and other stake holders. Common questions include: </p>
<p>How does a story get from inception to implementation?<br />
Which members of the team are responsible for maintaining Gherkin and Steps?<br />
What are the benefits of using an integration testing tool over just unit testing?<br />
What role does Behat testing play in the sign off process? </p>
<p>I&#8217;ll answer some of these questions in this post by looking at the reasons Behat was adopted at my previous employer SkyBet* and the workflows developed to support it&#8217;s use. We started using Behat at the v1.0 stage and over time hammered out a process to get a story from inception to build, giving each member of the production team responsibilities and putting a process in place for creating acceptance criteria. </p>
<p>Some background is required as to the kind of applications and products developed at Sky to understand why Behat and integration testing were deemed a necessary part of our testing plan. SkyBet have a number of customer facing websites including Sky Vegas, Sky Bet and Sky Poker. As you can imagine with a gaming website, handling customer interactions, data from gaming information providers as well as general CMS content complexity builds up quickly in many areas of the architecture. With this context it&#8217;s easy to see why testing that each level of the architecture integrates correctly is important. This accomplished this by testing all internal API&#8217;s consumed by the various Sky products using Behat. </p>
<p>Behat proved to be a great tool as it allowed all members of a multi disciplined team to understand what was the required outcome of a story and what features of that story were covered in the tests. This was a benefit provided by Gherkin, the human readable test description language at the heart of Behat. </p>
<p>What do I mean by a multi disciplinary team? This is a team composed of a number of different roles: The product owner, business analysts, testers and developers. It&#8217;s common to find teams like this in bigger organisations or software houses, in smaller organisations the roles still exist but members of a team may &#8216;wear many hats&#8217;.</p>
<p>I&#8217;ll now walk through the process of defining a story, testing it and developing it with reference to the roles listed above. </p>
<p>At the beginning of a cycle the product owner will define objectives (usually taking them from a product backlog). These objectives are then formalised into stories by the business analysts. This process involves producing a small requirements document with information about the feature and suggestions on key points of functionality to test. They are well placed to do this because of their in depth product knowledge and experience of the business domain.</p>
<p>This document is then passed to the tester who will own the testing process for the story. The tester then translates the requirements doc into Gherkin. In theory BA&#8217;s could write the Gherkin, it&#8217;s human readable, they should just be able to write what they expect the test to accomplish. The reason why this isn&#8217;t the approach taken is that it is the testing teams responsibility to maintain the Gherkin dialect used in the test suite. Their in depth knowledge of which steps to use to accomplish certain tasks (data creation and verification steps in particular) ensure maximum step re-use. The output of this stage is a battery of Gherkin scenarios designed to test all the behaviour of the feature under test. The task is then passed to the developer/s responsible for implementing the feature.</p>
<p>The developer is in a great position at the start of the development phase of the cycle as they have a well defined feature to develop. In later stages of a project when a large number of steps have already been implemented the Behat tests may even run without the development of additional steps. This is one of the key benefits of having experts in a projects &#8216;dialect&#8217; of Gherkin, step reuse.<br />
At this point the developer would implement any undefined steps and then use the tests to develop the feature against.</p>
<p>The final stage of the test / development cycle is formal acceptance of a feature by testers and then BA&#8217;s. Providing the feature was well defined in the early stages of the cycle a green Behat test suite should prove a feature is complete. In reality manual testing is often required to verify the scenarios have been interpreted and implemented correctly. </p>
<p>Thats a summary of the integration and acceptance process employed at SkyBet. It provides real benefits: the time taken to develop a  feature decreased (less back and forth between the parties involved in test/dev) and decreased defects in production (continually running the tests at build time catches errors pre deployment). </p>
<p>I think the process defined here also stays true to the BDD principles which Behat extolls. Stories (and behaviour) are defined by stakeholders and are written in Gherkin a language all stake holders can understand. Developers are supplied with tests ahead of feature development so they can use them to produce the feature closely to the specification.   </p>
<p>Are you using Behat in production or within a larger team? Let me know what you think of these workflows in the comments section. </p>
<p><em>* My relationship with SkyBet: Until recently I worked as a Software Engineer at SkyBet. A move to London to and contracting meant I finished working there in Jan 2012. They are an excellent company and are also recruiting!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ben-waine.co.uk/blog/behat/using-behat-in-a-large-multi-disiplined-team.php/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP Barcelona (PHPBC11) &#8211; Acceptance &amp; Integration Testing With Behat</title>
		<link>http://www.ben-waine.co.uk/blog/uncategorized/php-barcelona-phpbc11-acceptance-integration-testing-with-behat.php</link>
		<comments>http://www.ben-waine.co.uk/blog/uncategorized/php-barcelona-phpbc11-acceptance-integration-testing-with-behat.php#comments</comments>
		<pubDate>Sat, 22 Oct 2011 10:48:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpbc11]]></category>

		<guid isPermaLink="false">http://www.ben-waine.co.uk/blog/?p=205</guid>
		<description><![CDATA[Next weekend is the fourth edition of PHP Barcelona. I&#8217;m giving a two hour workshop on Acceptance &#038; Integration Testing with Behat.
Behat is a relatively new testing tool and is centred round the Behavioural Driven Development methodology.  
The workshop will consist of an introduction followed by a number of practical exercises. By the end [...]]]></description>
			<content:encoded><![CDATA[<p>Next weekend is the fourth edition of PHP Barcelona. I&#8217;m giving a two hour workshop on Acceptance &#038; Integration Testing with Behat.</p>
<p><a href="http://behat.org/">Behat</a> is a relatively new testing tool and is centred round the Behavioural Driven Development methodology.  </p>
<p>The workshop will consist of an introduction followed by a number of practical exercises. By the end of the workshop attendees will be able to write and execute Behat tests and should be ready to use Behat in their projects.</p>
<p>In order to gets the most out of the session I&#8217;ve asked attendees to set up LAMP and Behat before hand. </p>
<p>Heres What you need: </p>
<p><strong>NOTE: If you are unable to meet these set up requirements I will be running a &#8216;Behat Setup Clinic&#8217; on Friday. Follow <a href="http://twitter.com/#!/bwaine">me on Twitter</a> for details. </strong>    </p>
<p>1) Apache (pref with new VHOST Set up).<br />
2) PHP 5.3 (Command line and Set up with Apache)<br />
3) Behat (runnable from the command line)<br />
    &#8211; <a href="http://docs.behat.org/quick_intro.html"> Behat Quick Start</a><br />
4) Java (required for Sahi)<br />
    &#8211; <a href="http://www.java.com/en/download/index.jsp">Java Install</a><br />
5) Sahi<br />
    &#8211; <a href="http://sourceforge.net/projects/sahi/files/">Sahi Install</a></p>
<p>This seems like a lot of set up but in reality I expect most attendees working with PHP to have much of this set up already. </p>
<p>I look forward to seeing you at my workshop!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ben-waine.co.uk/blog/uncategorized/php-barcelona-phpbc11-acceptance-integration-testing-with-behat.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Behat &amp; XDebug: Debugging Steps.</title>
		<link>http://www.ben-waine.co.uk/blog/development/behat-xdebug-debugging-steps.php</link>
		<comments>http://www.ben-waine.co.uk/blog/development/behat-xdebug-debugging-steps.php#comments</comments>
		<pubDate>Mon, 10 Oct 2011 20:47:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[behat]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[xdebug]]></category>

		<guid isPermaLink="false">http://www.ben-waine.co.uk/blog/?p=178</guid>
		<description><![CDATA[Occasionally when writing complicated steps in Behat it&#8217;s useful to debug them (perhaps to find out why your tests are failing!).
The Behat test runner is actually just a PHP script run from the command line. As such by declaring a special variable before running the test runner we can trigger a remote debugging session on [...]]]></description>
			<content:encoded><![CDATA[<p>Occasionally when writing complicated steps in Behat it&#8217;s useful to debug them (perhaps to find out why your tests are failing!).</p>
<p>The Behat test runner is actually just a PHP script run from the command line. As such by declaring a special variable before running the test runner we can trigger a remote debugging session on your favorite IDE.</p>
<p>From the XDebug manual: </p>
<blockquote>
<p>When running the script from the command line you need to set an environment variable, like:<br />
export XDEBUG_CONFIG=&#8221;idekey=session_name&#8221;<br />
php myscript.php<br />
You can also configure the xdebug.remote_host, xdebug.remote_port, xdebug.remote_mode and xdebug.remote_handler in this same environment variable. All those configurable settings can also be set with normal php.ini settings.</p>
</blockquote>
<p><a href="http://xdebug.org/docs/remote">Full Text Here</a></p>
<p>To trigger a session from the test runner we should use a command similar to the following:</p>
<pre>
XDEBUG_CONFIG="idekey=session_name" behat path/to/tests
</pre>
<p>For this to work a debugging session must be started in your IDE (eg &#8211; In Netbeans: Project Menu > debug).</p>
<p>Typing this over and over again can get irritating so the next logical step is to set up an alias.</p>
<p>Edit your .bash_profile or .bashrc file using your terminal like so: </p>
<pre>

> nano ~/.bash_profile

// Then add the following line:

alias behatxc='XDEBUG_CONFIG="idekey=session_name" behat'
</pre>
<p>Now when you want to run the steps and trigger a debugging session use the command: &#8216;bashxc&#8217;. When you want to run the test runner normally use the regular Behat command.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.ben-waine.co.uk/blog/development/behat-xdebug-debugging-steps.php/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Behat &amp; XDebug: Testing &amp; Debugging API Calls</title>
		<link>http://www.ben-waine.co.uk/blog/development/behat-xdebug-testing-debugging-api-calls.php</link>
		<comments>http://www.ben-waine.co.uk/blog/development/behat-xdebug-testing-debugging-api-calls.php#comments</comments>
		<pubDate>Wed, 21 Sep 2011 22:08:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[behat]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[xdebug]]></category>

		<guid isPermaLink="false">http://www.ben-waine.co.uk/blog/?p=169</guid>
		<description><![CDATA[During office hours I work on a large PHP Application, we use a service oriented architecture and the application exposes a number of API&#8217;s. Recently we have been using Behat and writing BDD tests in Gherkin to test the behaviour of our various APIs.
When developing I always use XDebug&#8217;s remote debugging functionality to examine application flow and [...]]]></description>
			<content:encoded><![CDATA[<p>During office hours I work on a large PHP Application, we use a service oriented architecture and the application exposes a number of API&#8217;s. Recently we have been using <a href="http://behat.org/">Behat</a> and writing BDD tests in <a href="http://docs.behat.org/guides/1.gherkin.html">Gherkin</a> to test the behaviour of our various APIs.</p>
<p>When developing I always use XDebug&#8217;s remote debugging functionality to examine application flow and to debug issues as they arise. Our integration tests populate the app&#8217;s database with data and set up a number of other resources. If a test is failing its really handy to be able to trigger XDebug breakpoints and walk through the execution of the API call under test while this known state is set up.</p>
<p>Here is a quick example of how it&#8217;s done:</p>
<p>The Gherkin Test (with some contrived steps):</p>

<div class="wp_syntax"><div class="code"><pre class="cucumber" style="font-family:monospace;">Feature: Xdebug example
         As a Behat user
         I want to debug API methods using xdebug
         To facilitate debugging failing tests
&nbsp;
Scenario: Basic HTTP Request
      Given I am using Behat
      When I call the api method
      Then I should hit a breakpoint</pre></div></div>

<p>And an example FeatureContext implimentation:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Features context.
 */</span>
<span style="color: #000000; font-weight: bold;">class</span> FeatureContext <span style="color: #000000; font-weight: bold;">extends</span> BehatContext
<span style="color: #009900;">&#123;</span>
    <span style="color: #009933; font-style: italic;">/**
     * Initializes context.
     * Every scenario gets it's own context object.
     *
     * @param   array   $parameters     context parameters (set them up through behat.yml)
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$parameters</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Initialize your context here</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @Given /^I am using Behat$/
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> iAmUsingBehat<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Dummy given step</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @When /^I call the api method$/
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> iCallTheApiMethod<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// create a new cURL resource</span>
        <span style="color: #000088;">$ch</span> <span style="color: #339933;">=</span> <span style="color: #990000;">curl_init</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// set URL and other appropriate options</span>
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_URL<span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;http://behat-test.dev/api.php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_HEADER<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_RETURNTRANSFER<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// The key to getting xdebug to break on breakpoints is this cookie</span>
        <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_COOKIE<span style="color: #339933;">,</span> <span style="color: #0000ff;">'XDEBUG_SESSION=netbeans-xdebug'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// grab URL and pass it to the browser</span>
        <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">curl_exec</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// close cURL resource, and free up system resources</span>
        <span style="color: #990000;">curl_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * @Then /^I should hit a breakpoint$/
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> iShouldHitABreakpoint<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Dummy then step</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The important bit in this sample is the line:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_COOKIE<span style="color: #339933;">,</span> <span style="color: #0000ff;">'XDEBUG_SESSION=netbeans-xdebug'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This sets a cookie which is picked up by XDebug. Xdebug then attempts to connect to your IDE inline with your xdebug settings in php.ini. This example uses CURL for simplicity but it&#8217;s possible to add cookies to Zend Frameworks Http Client and any other good HTTP client class.</p>
<p>All you have to do now is open your IDE or debugging client and start a debugging session. Then drop to the command line and use the behat command to run your tests. When the step containing the HTTP call is executed xdebug should connect to your IDE and break at any point you set.</p>
<p>Over the next day or two I&#8217;ll be looking to see if a tighter integration is possible. It would be good to trigger a debugging session from a UI test (via Mink&#8217;s feature context file perhaps).</p>
<p>Happy debugging!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ben-waine.co.uk/blog/development/behat-xdebug-testing-debugging-api-calls.php/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP Azure Contest Wrap Up</title>
		<link>http://www.ben-waine.co.uk/blog/php-azure/php-azure-contest-wrap-up.php</link>
		<comments>http://www.ben-waine.co.uk/blog/php-azure/php-azure-contest-wrap-up.php#comments</comments>
		<pubDate>Mon, 16 May 2011 02:44:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP Azure]]></category>
		<category><![CDATA[#phpazurecontest]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.ben-waine.co.uk/blog/?p=105</guid>
		<description><![CDATA[Over the past couple of months I&#8217;ve participated in the #PHPAzureContest. As I was doing a large body of work for my dissertation it seemed like a good opportunity to try something new and get my project running on a new platform.
A Quick Recap Of The Product
The product is called &#8216;Twitter Sentiment Engine&#8217;. It looks [...]]]></description>
			<content:encoded><![CDATA[<p>Over the past couple of months I&#8217;ve participated in the #PHPAzureContest. As I was doing a large body of work for my dissertation it seemed like a good opportunity to try something new and get my project running on a new platform.</p>
<p><span style="text-decoration: underline;">A Quick Recap Of The Product</span></p>
<p>The product is called &#8216;Twitter Sentiment Engine&#8217;. It looks at the sentiment towards search terms on Twitter. It first assembles a training sample of Tweets using the Twitter Search API and then monitors the search terms using the Twitter Streams API. A basic user interface is provided for monitoring the results of the analysis. A full explanation of the product can be found in <a title="TSE - A Proper Introduction" href="http://www.ben-waine.co.uk/blog/php-azure/twitter-sentiment-engine-a-proper-introduction.php" target="_blank">this</a> post.</p>
<p><span style="text-decoration: underline;">At The End Of The Competition What Shape Is The Product In?</span></p>
<p>The product itself is very much a proof of concept, I have put little work into the UI and instead concentrated on the sentiment calculation implementation and building the two RESTful API&#8217;s (public and private &#8211; both hosted on Azure) that gather the data from Twitter.</p>
<p>The project is in three tears. The API (hosted on Azure) marshals requests from the other two elements, the UI and the worker nodes.</p>
<p><em>The UI</em></p>
<p>The UI of the project is a basic interface to the data gathered by the components below. It allows new keywords to be tracked, tracked keywords to be monitored and shows graph and tabular output of the data gathered on tracked keywords.</p>

<a href='http://www.ben-waine.co.uk/blog/php-azure/php-azure-contest-wrap-up.php/attachment/queue_architecture' title='Queue_Architecture'><img width="109" height="150" src="http://www.ben-waine.co.uk/blog/wp-content/uploads/2011/05/Queue_Architecture.jpg" class="attachment-thumbnail" alt="" title="Queue_Architecture" /></a>
<a href='http://www.ben-waine.co.uk/blog/php-azure/php-azure-contest-wrap-up.php/attachment/screen-shot-2011-05-08-at-11-03-20' title='Screen shot 2011-05-08 at 11.03.20'><img width="150" height="111" src="http://www.ben-waine.co.uk/blog/wp-content/uploads/2011/05/Screen-shot-2011-05-08-at-11.03.20.png" class="attachment-thumbnail" alt="" title="Screen shot 2011-05-08 at 11.03.20" /></a>
<a href='http://www.ben-waine.co.uk/blog/php-azure/php-azure-contest-wrap-up.php/attachment/screen-shot-2011-05-08-at-11-03-09' title='Screen shot 2011-05-08 at 11.03.09'><img width="150" height="110" src="http://www.ben-waine.co.uk/blog/wp-content/uploads/2011/05/Screen-shot-2011-05-08-at-11.03.09.png" class="attachment-thumbnail" alt="" title="Screen shot 2011-05-08 at 11.03.09" /></a>
<a href='http://www.ben-waine.co.uk/blog/php-azure/php-azure-contest-wrap-up.php/attachment/screen-shot-2011-05-08-at-11-02-51' title='Screen shot 2011-05-08 at 11.02.51'><img width="150" height="148" src="http://www.ben-waine.co.uk/blog/wp-content/uploads/2011/05/Screen-shot-2011-05-08-at-11.02.51.png" class="attachment-thumbnail" alt="" title="Screen shot 2011-05-08 at 11.02.51" /></a>
<a href='http://www.ben-waine.co.uk/blog/php-azure/php-azure-contest-wrap-up.php/attachment/screen-shot-2011-05-08-at-11-02-05' title='Screen shot 2011-05-08 at 11.02.05'><img width="150" height="108" src="http://www.ben-waine.co.uk/blog/wp-content/uploads/2011/05/Screen-shot-2011-05-08-at-11.02.05.png" class="attachment-thumbnail" alt="" title="Screen shot 2011-05-08 at 11.02.05" /></a>

<p><em>Worker Nodes</em></p>
<p>Worker nodes are the work horse of the application. They make requests to <em>The API</em> which allocates them jobs to work on. Jobs consist of new keywords to track (which require a training sample to be gathered) or an instruction to create and monitor a Twitter stream for a tracked keyword.</p>
<p><em>The Fulfilment API</em></p>
<p>The fulfilment API is my first attempt at creating a fully RESTful API using APP.  It glues the UI and worker nodes together. It is responsible for provisioning incoming requests to track new keywords, exposing processing jobs to worker nodes (sample gathering and stream monitoring) and exposing data to the UI to display.</p>
<p>This is the element of the architecture hosted on Azure. It also makes use of a SQL Azure database to sotre data gathered on keywords and data used in maintaining the state of a keyword (whether in sampling or tracking).</p>
<p>The diagram below shows some of the interactions:</p>
<p style="text-align: center;"><a href="http://www.ben-waine.co.uk/blog/wp-content/uploads/2011/05/Fulfillment_API.jpg"><img class="aligncenter size-full wp-image-107" title="Fulfillment_API" src="http://www.ben-waine.co.uk/blog/wp-content/uploads/2011/05/Fulfillment_API.jpg" alt="" width="360" height="96" /></a></p>
<p style="text-align: left;"><span style="text-decoration: underline;">Azure: The Good &amp; The Bad</span></p>
<p style="text-align: left;"><em>Component Used</em></p>
<p style="text-align: left;">I hosted the fulfillment API on an Azure extra-small compute instance and I used SQL Azure as the database for the project.</p>
<p style="text-align: left;">I found I need more control over the worker processes so these were hosted on a Windows Server 208 VPS on Rackspace. More on this later.</p>
<p style="text-align: left;"><em>The Good</em></p>
<ol>
<li>SQL Azure was pretty fantastic. Microsoft have got it just right here. it &#8216;Just Works<strong>™&#8217;.</strong> It&#8217;s fully compatible with SQL Management Studio which compares favorably to the MySQL gui tools. It is also very easy to provision new databases and set up access white lists. The PDO_SQLSRV driver allows PHP developers to access SQLSRV in a familiar way. The Doctrine 2 project support this driver which allowed me to use Doctrine 2 as the DBAL / ORM for the project.  See <a title="SQL Azure" href="http://www.ben-waine.co.uk/blog/php-azure/creating-and-using-an-sql-azure-database.php">here</a> for my brief post on setting up an SQL Azure instance.</li>
<li>The Windows Azure Command Line Tools For PHP are also a good innovation from the Microsoft Camp. The tools provide a mechanism for packaging PHP projects, testing them on Dev Fabric and then preparing them for a release on the live platform. In my opinion this is perforable to forcing developers to use Eclipse PDT to release project. The PHP IDE market is a lot more varied than the Microsoft /.net one (where VS is god). My criticism of the tools is that the learning curve is a little steep and documentation for packaging only the simplest of projects is available.</li>
<li>The platform management console: Good Points. The Azure Manager has a mechanism allowing a quick seemles switch between staging and production environments.</li>
</ol>
<p><em>The Bad</em></p>
<ol>
<li>Azure for PHP is a relatively new platform. The interoperability team are making great efforts to produce guides and tutorials on a wide range of subjects. While most of the time it was easy to find out the information I needed, frustratingly when encountering edge cases the guides and tutorials I needed wither were not there or I couldn&#8217;t find them using Google.  An example of this is how to offload PHP libraries to some other kind of storage (my attempt <a href="http://www.ben-waine.co.uk/blog/uncategorized/offloading-libraries-to-azure-blob-storage-initial-experiments.php" target="_blank">here</a>) to reduce upload time, creating an extra small compute instance with command line tools and gaining access to PHP error logs (my attempt<a href="http://www.ben-waine.co.uk/blog/php-azure/php-application-logging-on-azure.php" target="_blank"> here</a>).</li>
<li>Total Deployment Time. Each time a change is made to a project it&#8217;s entire source must be re packaged and uploaded to Azure. With the ZF and D2 in the project this took in excess of 30 min for packaging and upload. While there is a testing version of Azure often subtle differences meant that it could take three or four attempts to get a deployment right. Deployments where further hampered by a sometimes clunky interface to the platform manager screen.</li>
</ol>
<p><em>The Microsoft / PHP Experience In General </em></p>
<p>I was surprised and pleased to find that the Microsoft on PHP has a great community of people. A range of sites exist to help people find their feet on the MS platform.</p>
<p><a href="http://www.interoperabilitybridges.com/">Interoperability Bridge</a></p>
<p><a href="http://ubelly.com/">Ubelly</a></p>
<p><a href="http://blogs.msdn.com/b/brian_swan/">Brian Swan&#8217;s Blog</a> &#8211; Brain is MS PHP evangelist. He helped a lot with a few issues I had with the project.</p>
<p><a href="http://www.joshholmes.com/blog/">Josh Holmes&#8217;s Blog</a> &#8211; I met josh at PHPUK 2010 he has a few good PHP Azure Articles on his blog.</p>
<p><span style="color: #000000;"><a href="http://dev.juokaz.com/">Juozas Kaziukėnas Blog</a><span style="color: #333333;"> &#8211; Jo Is a Doctrine 2 Core Contributor. He is responsible for interop with Windows. </span></span></p>
<p><span style="color: #000000;"><span style="color: #333333;">In general I found that PHP on Microsoft to be a good platform to work on. As of PHP5.3, PHP is &#8216;feature complete&#8217; on windows and runs well on IIS. The IIS control pannel is also really smooth giving a nice graphical interface to site management. </span></span></p>
<p><span style="text-decoration: underline;"><span style="color: #333333;">What&#8217;s Next For The Project?</span></span></p>
<p><span style="color: #333333;"><span style="color: #333333;">Clearly the project is in it&#8217;s infancy, there is so much I&#8217;d like to do with it. The first step will to be re work the fulfillment API into a queue based architecture. Queues would allow a better and more reliable way to provision work between the worker processes. In addition it would allow a single point of contact with Twitter. This is more scalable than my current implementation of using Twitter Search API calls and Twitter Filter Streams both of which are rate limited.  The diagram bellow shows what this might look like. </span></span></p>
<p style="text-align: center;"><span style="color: #333333;"><span style="color: #333333;"><a href="http://www.ben-waine.co.uk/blog/wp-content/uploads/2011/05/Queue_Architecture1.jpg"><img class="aligncenter size-full wp-image-131" title="Queue_Architecture" src="http://www.ben-waine.co.uk/blog/wp-content/uploads/2011/05/Queue_Architecture1.jpg" alt="" width="329" height="451" /></a></span></span></p>
<p style="text-align: left;"><span style="color: #333333;"><span style="color: #333333;"><span style="text-decoration: underline;">Finally</span></span></span></p>
<p style="text-align: left;"><span style="color: #333333;"><span style="color: #333333;">Thanks to those who helped me along the way, I&#8217;ve enjoyed participating in the contest and I look forward to working on the Azure platform in the future.</span></span></p>
<p><span style="text-decoration: underline;"><br />
</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ben-waine.co.uk/blog/php-azure/php-azure-contest-wrap-up.php/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Offloading Libraries To Azure Blob Storage: Initial Experiments</title>
		<link>http://www.ben-waine.co.uk/blog/uncategorized/offloading-libraries-to-azure-blob-storage-initial-experiments.php</link>
		<comments>http://www.ben-waine.co.uk/blog/uncategorized/offloading-libraries-to-azure-blob-storage-initial-experiments.php#comments</comments>
		<pubDate>Sun, 15 May 2011 21:38:55 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP Azure]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[#phpazurecontest]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHPOnWindows]]></category>

		<guid isPermaLink="false">http://www.ben-waine.co.uk/blog/?p=151</guid>
		<description><![CDATA[In a previous post I&#8217;ve mentioned one of the big pain points on Azure for PHP developers is that it&#8217;s necessary  to upload the frameworks or libraries used in an application each time you push to Azure.
It was suggested that one way in which to get round this is to move your libraries to Azure blob [...]]]></description>
			<content:encoded><![CDATA[<p>In a previous post I&#8217;ve mentioned one of the big pain points on Azure for PHP developers is that it&#8217;s necessary  to upload the frameworks or libraries used in an application each time you push to Azure.</p>
<p>It was suggested that one way in which to get round this is to move your libraries to Azure blob storage. This isnt a supported solution but I thought I&#8217;d give it a go. At the moment it takers roughly 40 min to package my application and then upload it to Azure. Note: These are just initial experiments. The process outlined below doesn&#8217;t work yet (although it&#8217;s pretty close)!</p>
<p>Blob storage is almost a flat file system. It&#8217;s laid out in the following format:   account&gt;&gt;container&gt;&gt;blob.</p>
<p>By contrast most libraries have a very nested structure. In my example I&#8217;ll use Zend Framework. The class Zend_Log_Writter is stored in the file:   lib &gt;&gt;Zend &gt;&gt; Log &gt;&gt; Writer.php</p>
<p>The first logical step is to flattern the library into a single folder using periods to denote the previously nested structure of the files. EG: Zend.Log.Writter.php would be the name of a blob stored in the container &#8216;zend&#8217;. I achieved this using a simple command line script using php and the SPL iterators.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$args</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'argv'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$source</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$dest</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$rSourceDir</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RecursiveDirectoryIterator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$source</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$rSourceDirItr</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RecursiveIteratorIterator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$rSourceDir</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$transArray</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rSourceDirItr</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">/* @var $file SplFileInfo  */</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000088;">$realPath</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$file</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getRealPath<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$flatPath</span> <span style="color: #339933;">=</span> flatFileName<span style="color: #009900;">&#40;</span><span style="color: #000088;">$realPath</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$destination</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dest</span> <span style="color: #339933;">.</span> <span style="color: #009900; font-weight: bold;">DIRECTORY_SEPARATOR</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$flatPath</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #990000;">copy</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$realPath</span><span style="color: #339933;">,</span> <span style="color: #000088;">$destination</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> flatFileName<span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$pos</span> <span style="color: #339933;">=</span> <span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Zend'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$path</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pos</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$path</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">DIRECTORY_SEPARATOR</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'.'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$path</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$path</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The script takes two arguments: the source (nested library directory) and a destination directory (for the flattened structure).</p>
<p>After this process it&#8217;s worth inspecting the flat folder to ensure the results are consistent to what you expected. After this I used a similar script to upload the files to Azure Blob Storage.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">include</span> <span style="color: #0000ff;">'conf.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Set up Microsoft Azure SDK Autoloading</span>
&nbsp;
<span style="color: #990000;">set_include_path</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">get_include_path</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> PATH_SEPARATOR <span style="color: #339933;">.</span> AZURE_SDK<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Microsoft/AutoLoader.php'</span><span style="color: #339933;">;</span>
&nbsp;
Microsoft_AutoLoader<span style="color: #339933;">::</span><span style="color: #004000;">Register</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$storageClient</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Microsoft_WindowsAzure_Storage_Blob<span style="color: #009900;">&#40;</span>AZURE_HOST<span style="color: #339933;">,</span> AZURE_ACNAME<span style="color: #339933;">,</span> AZURE_PACCESS<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Check Args are in order</span>
&nbsp;
<span style="color: #000088;">$args</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'argv'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'1'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'2'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'invalid arguments supplied'</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$source</span>   <span style="color: #339933;">=</span> <span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$destCont</span> <span style="color: #339933;">=</span> <span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">is_dir</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$source</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'source is not file'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$storageClient</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>containerExists<span style="color: #009900;">&#40;</span><span style="color: #000088;">$destCont</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$storageClient</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>createContainer<span style="color: #009900;">&#40;</span><span style="color: #000088;">$destCont</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Folder should be flat</span>
<span style="color: #000088;">$recSourceDir</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RecursiveDirectoryIterator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$source</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$recSourceDir</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$storageClient</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>putBlob<span style="color: #009900;">&#40;</span><span style="color: #000088;">$destCont</span><span style="color: #339933;">,</span> <span style="color: #000088;">$file</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getFileName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$file</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getRealPath<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;PUT - &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$file</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getFilename<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This is likely to take some time as each file is uploaded individually.</p>
<p>The next step in the process is to set up an autoloader to get required files from Azure.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Flat_Autoloader
<span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Blob Storage Class
     *
     * @var Microsoft_WindowsAzure_Storage_Blob
     */</span>
    <span style="color: #000000; font-weight: bold;">private</span> static <span style="color: #000088;">$blob</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Registers the autoloader
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> Register<span style="color: #009900;">&#40;</span><span style="color: #000088;">$blob</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$blob</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$blob</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$blob</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>registerStreamWrapper<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'blob'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">spl_autoload_register</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Flat_AutoLoader'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Load'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009933; font-style: italic;">/**
     * Load a class
     *
     * @param string $className Class name to load
     */</span>
    <span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> Load<span style="color: #009900;">&#40;</span><span style="color: #000088;">$className</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Get the file name from the class name.</span>
&nbsp;
        <span style="color: #000088;">$partArray</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'_'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$className</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$containerName</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$partArray</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$flatClass</span> <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'.'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$partArray</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'.php'</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$containerName</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot; &quot;</span> <span style="color: #339933;">.</span>  <span style="color: #000088;">$flatClass</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$blob</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>blobExists<span style="color: #009900;">&#40;</span><span style="color: #000088;">$containerName</span><span style="color: #339933;">,</span> <span style="color: #000088;">$flatClass</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'blob://'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$containerName</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$flatClass</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The class takes an instance of the Azure Blog storage class from the Windows Azure SDK and on registration of the autoloader ensures that the &#8216;blob&#8217; stream is available for future use. In the Load method the incoming class name is exploded and the first part of the class name (&#8216;Zend&#8217;) is used as the container to look for the class file in. The blob name is the imploded class name (with &#8216;.&#8217; substituting any instances of &#8216;_&#8217;).</p>
<p>The container  / blob combination is the required.</p>
<p><span style="text-decoration: underline;">Caveats</span></p>
<p>There are two main caveats to using this approach to autoload files on Azure.</p>
<p>1) The included files may not themselves use <em>require / include </em>statements as these will fail. <a title="removing require_once" href="http://gogs.info/2008/10/removing-require_once-calls-from-zend-framework/" target="_blank">This article</a> outlined a method for removing all the require_once calls from Zend Framework.</p>
<p>As the blog above mentions there is one <em>require_once </em>statement in Zend_Application that cannot be removed. After initially trying to override methods in Zend Application that trigger Zend_Autoloader I gave up. I think inheriting from Zend Application and Zend_Application_Bootstrap_Bootstrap then overriding the relevant methods is possible but is a project for the future.</p>
<pre>

% cd path/to/ZendFramework/library

% find . -name '*.php' -not -wholename '*/Loader/Autoloader.php' \
-not -wholename '*/Application.php' -print0 | \
xargs -0 sed --regexp-extended --in-place 's/(require_once)/\/\/ \1/g'
</pre>
<p>2) Requiring a file from blob storage has a particularly high performance penalty as it is done over http. The next logical step is to use  a byte code cache like APC or the Azure equivalent Win Cache to ensure that after an initial load the file is not recalled from blob storage again.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ben-waine.co.uk/blog/uncategorized/offloading-libraries-to-azure-blob-storage-initial-experiments.php/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

