Skip to content

Disaster!

Well!

I was scheduled to present Groovy and the other Gr8 technologies to the Hong Kong Java User Group on Thursday 9 May, 2013.

Unfortunately, I just (Tuesday 7 May, 2013) spent a rather uncomfortable night in Tai Po’s Alice Ho Miu Ling Nethersole Hospital and am now under strict {Doctor’s, Wife’s} orders not to exert myself for the next few days.

This means that I have had to cancel the presentation.

Apologies to any HKJUG member that was planning to come along.

Since there will be no chance to reschedule (at least for this year), I am putting the slide pack up anyway.

So: please enjoy The Future Is Gr8.

Once again, I apologise to the HKJUG for any inconvenience this causes.

Tags: , ,

Microsoft Simplifies IE Testing

Subtitle: Free Windows/IE VMs for testing purposes…
Sub-subtitle: …and other useful things to help IE and cross-browser site testing.

Part of the Modern.ie site.

Worth remembering.

Tags: ,

Prepending A Node With Groovy’s XmlParser

A recent question on the Groovy mailing list: how to update an XML document by prepending an element before another?

Not as completely trivial as it might sound.

Groovy’s XMLSlurper only allows for appending a node to a given node’s list of children and so one needs the services of XMLParser.

A teensy bit of fiddling is required, thusly:

def xml = """<x name="fred">
                <y name="bill">
                    <z>
                        <a index="0" size="10"/>
                    </z>
                </y>
                <y name="harry">
                    <z>
                        <a index="0" size="200"/>
                        <a index="1" size="500"/>
                    </z>
                </y>
             </x>"""

def x = new XmlParser().parseText(xml)

x.y.each { y ->
    int numA = 0
    int totalASize = 0
    y.z.a.each { a ->
        numA ++
        totalASize += a.@size.toInteger()
    }
    // add a new node as the 0th child, ie: before <z>
    y.children().add(0, new Node(null, 'summary', [numA:numA,totalASize:totalASize]))
} 

new XmlNodePrinter().print(x)

And the beautiful resultant XML is:

<x name="fred">
  <y name="bill">
    <summary numA="1" totalASize="10"/>
    <z>
      <a index="0" size="10"/>
    </z>
  </y>
  <y name="harry">
    <summary numA="2" totalASize="700"/>
    <z>
      <a index="0" size="200"/>
      <a index="1" size="500"/>
    </z>
  </y>
</x>

Not sure if it’s generally a good idea to depend on the specific ordering of elements in a document but it’s common (Apple’s [nasty] XML Property List format is one example that pops to mind) and–as I’ve shown above–can be done with XMLParser.

Tags: ,

Gorgeous GBench

I’ve been known to indulge my OCD and post a very few trivial micro-benchmarks.

Each time I just hacked a simple Groovy script together I thought “there must be a better way.”

Turns out, there is: GBench: “a benchmarking module for Groovy.”

To see how GBench works, I took an earlier benchmark and re-worked it for GBench, viz:

@Grab('com.googlecode.gbench:gbench:0.4.1-groovy-2.1') // v0.4.1 for Groovy 2.1

def r = benchmark(verbose: true) {
    'Each' {
        def i = 0
        (1..100000000).each { i ++ }
    }
    'For' {
        def i = 0
        for (x in 1..100000000) { i ++ }
    }
}
r.prettyPrint()

And the result:

Environment
===========
* Groovy: 2.1.2
* JVM: Java HotSpot(TM) 64-Bit Server VM (23.7-b01, Oracle Corporation)
    * JRE: 1.7.0_17
    * Total Memory: 127.875 MB
    * Maximum Memory: 127.875 MB
* OS: Windows 8 (6.2, amd64) 

Options
=======
* Warm Up: Auto (- 60 sec)
* CPU Time Measurement: On

Warming up "Each"...
Measuring "Each"...
Warming up "For"...
Measuring "For"...
            user  system         cpu        real

Each  7859375000       0  7859375000  8111961507
For   2250000000       0  2250000000  2304534377

Simple, easy. What’s not to like!

Tags: ,

Will Code For…Extraordinary Wealth

And to further that aim…Bob’s CV in all it’s Word 2010 .docx glory.

Those with checkbooks, please line up on the left. If you have cash, form a nice queue on my right. Please find your place in the queue, ordered descending based on the amount of money you wish to throw at me. Favourable consideration will be given to those wishing to sweeten the deal by offering me my own desert island/private jet, etc.

A man can dream, can’t he?

Triangle Groovy Koan

Thought I’d post a “Groovy Koan.”

The following is a Groovy version of a solution to the Triangle Ruby Koan, which (in part) challenges the student to code the following problem:

# Triangle analyzes the lengths of the sides of a triangle
# (represented by a, b and c) and returns the type of triangle.
#
# It returns:
#   :equilateral  if all sides are equal
#   :isosceles    if exactly 2 sides are equal
#   :scalene      if no sides are equal
#
def triangle(a, b, c)
  # WRITE THIS CODE
end

What you’ll see here arguably represents a ‘sexier’ solution than many others out there.

It’s not all my own work: its an amalgam of the various versions that were discussed during the workshop that I talked about earlier. So thanks to my fellow participants.

Here goes nothin’…

First, the solution:

// file: triangle/Triangle.groovy
package triangle

class Triangle {
    static triangle(_a, _b, _c) {
        def coll = [_a, _b, _c]
        def (a, b, c) = coll.sort()
        if ((a + b) <= c)
            throw new TriangleException()
        TriangleType.values()[coll.unique().size() - 1]
    }
}

// NB: order is important here
enum TriangleType {
    EQUILATERAL, ISOSCELES, SCALENE
}

class TriangleException extends Exception {}

Rather than follow the Ruby Koan testing path I have decided to find my own way and use the very neat Spock testing framework. Viz:

// file: TriangleSpec.groovy
import spock.lang.*
import triangle.*

public class TriangleSpec extends spock.lang.Specification {

    @Unroll("#iterationCount: <#a, #b, #c> represents an EQUILATERAL triangle.")
    def "test equilateral triangles have equal sides"(a, b, c) {
        expect:
        TriangleType.EQUILATERAL == Triangle.triangle(a, b, c)
        where:
         a |  b |  c
         2 |  2 |  2
        10 | 10 | 10
    }

    @Unroll("#iterationCount: <#a, #b, #c> represents an ISOSCELES triangle.")
    def "test isosceles triangles have exactly two sides equal"(a, b, c) {
        expect:
        TriangleType.ISOSCELES == Triangle.triangle(a, b, c)
        where:
         a |  b |  c
         3 |  4 |  4
         4 |  3 |  4
         4 |  4 |  3
        10 | 10 |  2
    }

    @Unroll("#iterationCount: <#a, #b, #c> represents a SCALENE triangle.")
    def "test scalene triangles have no equal sides"(a, b, c) {
        expect:
        TriangleType.SCALENE == Triangle.triangle(a, b, c)
        where:
         a |  b |  c
         3 |  4 |  5
        10 | 11 | 12
         5 |  4 |  2
    }

    @Unroll("#iterationCount: <#a, #b, #c> represents an illegal triangle.")
    def "test illegal triangles throw exceptions"(a, b, c) {
        when:
        Triangle.triangle(a, b, c)
        then:
        thrown(TriangleException)
        where:
        a | b |  c
        0 | 0 |  0
        3 | 4 | -5
        1 | 1 |  3
        2 | 4 |  2
    }
}

Does it work? Yes. Yes it does:

And in (a somewhat round-about) homage to Jim Wierich (author of Ruby’s equivalent ‘rake‘ tool), I have used Gradle for build automation and dependency management:

// file: build.gradle
apply plugin: "groovy"

repositories {
    mavenCentral()
}

dependencies {
    groovy("org.codehaus.groovy:groovy-all:2.0.5")
    testCompile "org.spockframework:spock-core:0.7-groovy-2.0"
}

// ALWAYS do tests regardless of up-to-date checking
test.outputs.upToDateWhen { false }

May the above help you along your journey on your path to enlightenment!

Tags: , , ,

YOW! Workshops 2012 – Brisbane

Had the opportunity to take a ramble on The Path to Enlightenment via Ruby Koans with Jim Weirich.

Good fun!

It would be remiss of me if I did not mention that Groovy Koans do exist…so Groovy devs do not need to miss out on enlightenment.

Tags: , ,

Functional Programming with the Stars

Thanks to all involved in making Functional Programming with the Stars a success.

Maybe one day I’ll properly grok Monads…

Tags:

Using Betamax to Mock HTTP-based Interactions

Another Groovymag contribution. This time from GroovyMag March 2012.

I thought the title was ‘clever’, even if no-one else liked it!

As usual, the project files are available


To Kill a Mocking Problem

Using Betamax to Mock HTTP-based Interactions

Bob Brown
bob@transentia.com.au
http://www.transentia.com.au

Extensively testing system components is a cornerstone idea of modern software development but, even with Groovy’s powerful toolset, is sometimes easier said than done. This is especially true when testing a feature in an HTTP-based application which relies on fixture data that is supplied via an interaction with another system. This article shows how Betamax can help.

Introduction

Some time ago, in a project not so far, far away from me I had a problem: I needed to run a test feature that required live fixture data from a “downstream” WebService. I couldn’t use the standard TEST environment because a colleague was reconfiguring it for his own nefarious purposes. I couldn’t work with the SIT environment because another team was using it. I couldn’t “borrow” the UAT environment since it was already booked out for testing an earlier change. Even the TRAIN environment was unavailable due to an influx of new staff. Stymied! Nothing left to do but hack on the documentation, darn it…

Those of you who work in a large multi-project, multi-department environment will surely recognize (and I hope, sympathise with) my all-too-common situation: there are simply never enough environments to go around.

Had I known about Rob Fletcher’s Betamax, I am sure that I could have saved myself a fair bit of aggravation and broken the dependency chain that linked my testing to the availability of another system.

To quote from the Betamax home page: “Betamax is a record/playback proxy for testing JVM applications that access external HTTP resources such as web services and REST APIs. ….The first time a test annotated with @Betamax is run any HTTP traffic is recorded to a tape and subsequent runs will play back the recorded HTTP response from the tape without actually connecting to the external server.”

As I was thinking about Betamax, my mind mixed together two somewhat disparate ingredients: mocking and archiving old movies. Once I had swirled them together, added a pinch of Geb and a dash of Spock to the cocktail, out poured the task at hand: to show how Spock and Geb can work together to automate scraping quotes from a web page dedicated to the old Gregory Peck classic movie “To Kill a Mockingbird”, and then marshaling the results into a JSON structure suitable for further processing. A second task is to illustrate how Betamax can accelerate things while decoupling the test from the actual web page’s availability.

Martin Fowler (the self-proclaimed “loud-mouth on the design of enterprise software”) would probably prefer that I called Betamax a stubbing system, rather than a mocking one but I couldn’t for the life of me come up with a nice punny stub-related ‘hook’ for the article, so for now I shall persist in calling it a mocking system. Follow the link given in the “Learn More” section for Martin’s excellent article on the matter.

This is not a real testing situation, in that I am not interested in actually testing anything. Nevertheless, I chose to use Spock for this task because it provides an excellent testing framework that is worth highlighting and because it integrates trivially easily with Betamax. I chose to use Geb to perform the actual web page scraping for the best of reasons: visibility, ease, compatibility and power.

The scraping task

The Spock/Geb code for this task is pretty simple. I have chosen to scrape the quotes from the “finestquotes.com” site. Figure 1 shows the contents and structure of the page I am scraping, as displayed by IE9’s Developer Tools.

Figure 1: Contents and structure of ‘finestquotes.com’ quotes page

The meta-task I am undertaking: writing an article covering how to bind different technologies together to scrape quotes from a web page, brings to mind the following—rather apposite—quote:

I have gathered a posie of other men’s flowers and nothing but the thread which binds them is my own.
—Michel Eyquem de Montaigne

Something to think about!

You should keep the structure of the page in mind as you read the Spock/Geb code given in Listing 1.

import geb.*
import geb.spock.*

import static org.apache.commons.lang.StringUtils.strip
import spock.lang.*
import groovy.json.*

class MockingBirdSpecification extends GebSpec {
  def "scrape 'To Kill a MockingBird' quotes"() {
    when:
      to FinestQuotesPage
    then:
      at FinestQuotesPage
    and:
      produceJSON()
  }

  void produceJSON() {
    new StringWriter().with { sw ->
      new StreamingJsonBuilder(sw).quotes() {
        generated new Date()
        title heading
        size quotes.size()
        quotes quotes.collect([]) { q ->
          [ quote: strip(q.quote, "   ~"), attribution: q.attribution]
        }
      }
    println JsonOutput.prettyPrint(sw.toString())
    }
  }
}

class FinestQuotesPage extends Page {
  static url =
    "http://www.finestquotes.com/movie_quotes" +
      "/movie/To%20Kill%20a%20Mockingbird/page/0.htm"
  static at = { title.startsWith('Quotes') }
  static content = {
    quotes {
      $("div#container1 > div", id: "containerin").collect {
        module Quote, it
      }
    }
    heading { $("div#middletitles strong").text() }
  }
}

class Quote extends Module {
  static content = {
    quote {
      $("span.indquote_link").text()
    }
    attribution {
      $("div", id: "authortab").text()
    }
  }
}

Listing 1: Screen-scraping a web page with Geb and Spock

Class MockingBirdSpecification shows Geb and Spock working together to access and scrape the quotes page. In this class, Spock supplies a JUnit-based testing framework while the feature “scrape ‘To Kill a MockingBird’ quotes” drives Geb through its activities.

Geb defines a page using a content domain-specific language (DSL). The FinestQuotesPage class shows this in action. The class gives definitions for the page’s URL, how to check if the page has been accessed correctly, how to access (using Geb’s JQuery-like selector language) the distinguished heading field and how to isolate from the HTML document each div element that acts as a container for the actual quote data. There are many such containers repeated throughout the document, one for each quote.

Each container div itself encloses a defined structure that contains the actual data for each individual quote. Geb supplies a module DSL that makes it easy to cater for the sort of structural repetition seen here. In Listing 1, the Quote class defines how to access the real quote and attribution data relative to its container. As the FinestQuotesPage class isolates each container div, it passes it to a Quote module and then gathers all the resultant Quote module instances into a list that is then exposed via its quotes property. This technique represents a slightly unusual way of working with Geb and is described by Betamax’s creator Rob Fletcher on his “Adhockery” blog (see the “Learn More” section for a reference). Clearly, Rob is a multi-talented guy!

The end result of all this is that the page and associated list modules have extracted all the tasty “meat” from the document and exposed it so that it can be easily manipulated. From this point it is simple to produce a JSON representation using Groovy’s StreamingJsonBuilder and JsonOutput classes.

It is important to understand that Geb has done all the hard work of isolating the distinguished parts of the HTML document “up front” and does it one time only. Subsequent access to the various page and module properties is quite efficient.

It is good to know that Geb can cope with invalid HTML. The HTML specification for the ID attribute says: “This attribute assigns a name to an element. This name must be unique in a document.” The HTML document we are working with here gives each container the same id attribute value (“containerin”) and within each container there is a div with an id attribute having the value “authortab.”

It is worth noting that when executed via Gradle, you will—by default—get nice “manager friendly” reports, as Figure 2 shows.

Figure 2: Spock report

Take a quick note of the time taken for this test to execute, we will refer to this later.

Pressing the ‘Betamax’ button

In the introduction I mentioned one of Betamax’s virtues: the ability to decouple the system under test from its downstream fixture data. Betamax has at least one other virtue: speed.

Consider Figure 2: 6.19 seconds to execute. Not too bad but if you are an agilist with a large number of tests forever chasing James Shore’s “ten minute build” ideal, you will want to do better. By avoiding all the messy network interactions implicit in getting hold of external data, Betamax can speed up test execution, often quite substantially.

Enough discussion, let’s see the code. Listing 2 shows the Betamax-augmented MockingBirdSpecification class. Clearly, it is trivial to bring Betamax to bear on a problem.

import geb.*
import geb.spock.*

import static org.apache.commons.lang.StringUtils.strip
import spock.lang.*
import groovy.json.*
import org.junit.Rule
import betamax.Betamax
import betamax.Recorder

class BetamaxMockingBirdSpecification extends GebSpec {
  @Rule Recorder recorder = new Recorder()

  @Betamax(tape="ToKillAMockingBird.tape")
  def "scrape 'To Kill a MockingBird' quotes"() {
    setup:
      browser.driver.setProxy("localhost", recorder.proxyPort)
    when:
      to FinestQuotesPage
    then:
      at FinestQuotesPage
    and:
      produceJSON()
  }

  void produceJSON() {
    […elided, unchanged…]
  }
}

Listing 2: The Betamax-augmented MockingBirdSpecification class

When you look at Listing 2, one thing should be immediately clear: it is trivial to include Betamax into a testing regime.

There are a number of points of interest in Listing 2.

Betamax uses a JUnit @Rule annotation attached to an instance of its Recorder class to allow the Recorder to hook into the lifecycle of the test and to start/shutdown Betamax’s “tape recorder” proxy (which is actually an embedded instance of Jetty). If you haven’t seen it before, an @Rule is effectively a JUnit 4.7+ extension mechanism that provides access to the JUnit lifecycle (@Rules were initially called ‘@Interceptors’—a name which still seems clearer to me).

The @Betamax annotation defines a ‘tape’ to use; Betamax will store the data arising from each request/response interaction into a tape (for the demo project the file src\test\resources\betamax\tapes\ToKillAMockingBird_tape.yaml). Betamax provides a number of other options (unneeded for this article) that can be set via the @Betamax annotation or on the Recorder instance itself. These include the ability to store only requests that match (part of) a given URI or header field values, setting a tape mode to READ_ONLY and setting a pass-through list of hosts that won’t be proxied.

It is worth noting that Betamax can also configure itself from external files. As the documentation says: “If you have a file called BetamaxConfig.groovy or betamax.properties somewhere in your classpath it will be picked up by the Recorder class.”

As an aside, it is interesting to see that Rob Fletcher has chosen to use YAML (via the plain Java SnakeYAML library) for the tape format. YAML is a superset of JSON which provides “human-readable data serialization format…data-oriented, rather than document markup.” YAML is certainly a better choice for this purpose than XML would have been, due to its superior (at least, easier) support for binary data types. What makes YAML a particularly good choice is that it makes it very easy to simply jump into a tape and edit it according to the needs of a test.

The last point of interest concerns configuring Geb to use Betamax’s embedded proxy. I have added an appropriate setup block to the “scrape ‘To Kill a MockingBird’ quotes” feature.

It is easy to see the effect of Betamax on the test. The first time this Betamax-enhanced test is executed it is slightly slower due to the overhead of creating the tape. Subsequent test executions match and replay the recorded interactions from the tape and so are much faster, as Figure 3 shows.

Figure 3: Betamax replay can be faster

Clearly, Betamax has had a big effect on the test’s execution time. Things are much faster (pretty much twice as fast) without the network overhead.

It is worth reemphasizing that with Betamax in the loop, our test has not needed to go back to the source system. The test is now decoupled from issues arising from the system becoming unavailable, mutating under us, throwing up its own set of bugs, etc., etc.

This is A Good Thing.

It gets better. If there were multiple tests within the same test suite, there would be a much bigger improvement: currently a large proportion of time is spent firing up Betamax’s Jetty-based proxy server to service just the one feature. This is very easy to see by making a copy of the Spock test and executing it alongside the original. Figure 4 shows the result.

Figure 4: Avoiding repeated proxy startup

A nearly 8 times speedup. That ten minute build ideal seems back in reach now, doesn’t it!

Wrapping up

You need to look at Betamax and see what it can do to for you.

Setting up fixture data for a unit test can be quite hard work and often drives people to create integration tests or simply leave things for manual acceptance testing. Betamax makes it as easy as possible to perform repeatable unit testing with high-level or complex fixture data and at the same time can break the interdependencies between systems that often become impediments to a nice steady workflow.

The pairing of Geb and Spock is pretty neat as well.

Although it is early days (Betamax is currently at version 1.0, with version 1.1 showing on the horizon), Betamax shows great promise and is definitely technology I’ll be keeping an eye on…I’d advise you to do the same.

Learn more

Bob Brown is the director and owner of Transentia Pty. Ltd.. Based in beautiful Brisbane, Australia, Bob is a specialist in Enterprise Java and has found his niche identifying and applying leading-edge technologies and techniques to customers’ problems.

Tags: , , , , ,

Strategy And Tactics And Architecture

A chance meeting with a friend this evening got me thinking…

He was undertaking (enthusiastically, it seems) TOGAF training. It was the end of the day and he seemed a little worn down. Not surprising really, he faces a herculean task.

The TOGAF version 9 book proudly announces announces it is 780 pages long:

And that’s just the framework!

I gather that the idea is he will become a “TOGAF Thought Leader” and can champion the roll out of TOGAF throughout the organisation.

It is assumed that things will improve when everyone can speak the same language about their architectural plans.

This got me musing:

[*1]

What? You didn’t catch that?

Oh well. Maybe you should take some Chinese Training. Then you can become a “Chinese Thought Leader” and can champion the roll out of Chinese throughout your organisation. Things are bound to improve once everyone can speak Chinese. [*2]

No?

Surprised?

The TOGAF approach is rooted in the time when we hoped that open standards would prevail. In this nirvana we were all running OSF/1 (distributed via ANDF, naturally) and programming in Ada.

Today’s world isn’t like that. We have brought down upon ourselves an increasing number of OSs, a plethora of different languages, some good interoperability technologies, and vendors that work both assiduously and insidiously to subvert any semblance of neutrality to ensure that their clients are locked in to their product set.

Here’s the hard truth from our industry’s history: you can strategise all you want but you won’t succeed unless you retain tactical flexibility.

IMHO, these days one should focus hard on tactics, not strategy. You can achieve something tactically, but the war is never ending (and thus can’t be won).

To put it another way (paraphrasing Helmuth von Moltke the Elder): No battle plan ever survives contact with the enemy.

More is not better. If your framework on its own amounts to 780 dense pages, you have simply no chance.
Your clients won’t understand it. Your team won’t follow it. Your vendors won’t tolerate it.

There is but one single Critical Success Factor here: simplicity.

KISS. It’s your only chance.

You can’t have a single all-encompassing architecture. You can’t expect everyone to get on board. The world will not stand still–you won’t even have time to formulate the Grand Plan.

Darn but this ‘architecture’ idea is soooo seductive though isn’t it: maybe it’ll all work this time

Not going to happen, though.

To get back to military terms…the strategy has been decided: you are already in the war; you now must focus on constantly adapting your tactics.

Gotta say I feel a bit sorry for my friend! The organisation under whose flag he labours was established precisely on the promise that it will control his clients’ worlds and guide them to a well-designed, static and completely regulated nirvana.

For them, there is no politically accepable alternative.

For them, Agile Architecture just isn’t possible.

And yet history shows us it probably is the only thing that might be useful, not to say appropriate.

A losing battle, if ever there was one.

[*1]: Maybe any problems you are having with your architechure aren’t actually related to the langauge being used to describe said architecture.

[*2]: I’m actually all in favour of learning Chinese…

C, Java Enterprise Edition, JEE, J2EE, JBoss, Application Server, Glassfish, JavaServer Pages, JSP, Tag Libraries, Servlets, Enterprise Java Beans, EJB, Java Messaging Service JMS, BEA Weblogic, JBoss, Application Servers, Spring Framework, Groovy, Grails, Griffon, GPars, GAnt, Spock, Gradle, Seam, Open Source, Service Oriented Architectures, SOA, Java 2 Standard Edition, J2SE, Eclipse, Intellij, Oracle Service Bus, OSB