Friday, 3 January 2014

Fixing FireWire audio interface instability under OSX Mavericks

A variation from my usual blog topics today, but hopefully this helps someone. I have been a happy user of the Tascam FireOne FireWire audio/MIDI interface ever since picking one up for a bargain price a couple of years ago. As a recovering music-gearaholic, I embraced its minimal dimensions, and together with GarageBand on the Mac, it has allowed me to eBay vast amounts of outboard equipment while actually improving the quality of the music I create. Thus confirming a suspicion I had at the peak of my gear-hoarding tendencies:
More Music-Making Gear == More Distraction From Making Music
But I digress. Despite being technically unsupported since OSX 10.5 Leopard The FireOne worked perfectly for me right up to (and including) OSX 10.8 Mountain Lion, so when 10.9 Mavericks was released I gleefully jumped aboard.

And was horrified when within a few seconds of playback in GarageBand, the entire hardware-software combination locked up, sounded garbled and/or complained about sample-rate problems. This was not good and I thought that either Apple had broken FireWire timing accuracy in Mavericks (perhaps as part of their timer-coalescing improvements) or I was just SoL and would have to shell out for a new audio interface.

As it turns out, neither was true.

If you are experiencing problems working with external devices under audio applications (my particular combination being a FireWire interface and GarageBand) your first action should be:
  • Open Finder/Applications
  • Find GarageBand (or the app giving trouble)
  • Right-click -> Get Info
  • Check Prevent App Nap
This is slightly counter to the Apple's own statement on App Nap which states:
if that app isn’t currently doing something for you — playing music, downloading a file or checking email, for example — App Nap conserves valuable battery life by slowing down the app
But I'm not too upset - it's an easy fix and the extra battery life is definitely worth the upgrade.

Thursday, 19 December 2013

Conditional SBT Keys for Jenkins Builds

A little SBT snippet that's proven useful (place this in a file like jenkins-only.sbt alongside your build.sbt):
    // Settings which should only be applied if this SBT is being run by Jenkins

    // Jenkins nodes always have $JENKINS_URL set - that is our telltale:
    lazy val underJenkins:Option[String] = scala.util.Properties.envOrNone("JENKINS_URL")
    def ifUnderJenkins[T](setting: => T):Seq[T] = underJenkins.map ( s=> setting ).toSeq


    // Write a JUnit-format output especially for Jenkins:

    testOptions in Test ++= ifUnderJenkins ( Tests.Argument("junitxml") )

Why: Well in this case, it gives Jenkins the output he/it needs to do pretty "Test Result Trend" graphs and have clickable error messages when tests fail, while simultaneously giving developers the well-structured, detailed test output that SBT gives by default.
How: As mentioned in the code comments, and in the Jenkins documentation, a Jenkins node will have the JENKINS_URL environment variable set, and a dev (probably) won't.
Nice Features:
  • Exploits the fact that an Option[T] can be converted to a zero-or-one-length Seq[T] with toSeq()
  • Parameterized ifUnderJenkins so that any SBT key can be handled conditionally
  • By-name parameter (that's the setting: => T ) means the setting won't even be evaluated unless needed

Monday, 18 November 2013

Argument Capture with Scala / Specs2 / Mockito, part 2: The neater way

So in my last post, I indicated my dissatisfaction with the ugliness of creating a Mockito ArgumentCaptor in Scala - turns out someone else had the same thought, and it's already fixed in Specs2:
  "Application Main Controller" should {

    "Pass a non-empty list to the template" in {
      val result = controller.newsAction(FakeRequest())
      status(result) must beEqualTo(200)

      val captor = capture[List[String]]

      there was one(mockedNewsRenderer).apply(captor)
      val theArgument = captor.value
      theArgument.isEmpty must beFalse
    }
  }

Nice.

Sunday, 17 November 2013

Using Mockito's ArgumentCaptor in Scala

I've been doing what an old colleague of mine used to call "Stack-Whoring" a bit recently - trying to get a few more badges and also up my general reputation on Stack Overflow. It's been fun and educational, and I wanted to post (mainly for my own reference) how to use Mockito's powerful ArgumentCaptor facility from inside a Specs2 example:

I'm just going to nab my own answer from the relevant SO question:
class ApplicationSpec extends Specification with Mockito {

  val mockedNewsRenderer = mock[List[String] => Html]

  val controller = new ApplicationController {
    override def renderNews(s:List[String]) = mockedNewsRenderer(s)
  }

  "Application News Controller" should {

    "Pass a non-empty list of news items to the template" in {
      val result = controller.newsAction(FakeRequest())

      status(result) must beEqualTo(200)

      val captor = ArgumentCaptor.forClass(classOf[List[String]])

      there was one(mockedNewsRenderer).apply(captor.capture())
      val theArgument = captor.getValue
      theArgument.isEmpty must beFalse
    }
  }
}
The trickiest bit (if you're already familiar with ArgumentCaptor usage in Java) is the use of classOf[T] to get the Scala equivalent of Java's .class so you can then call ArgumentCaptor.forClass().

There's probably scope there for a Pimp My Library tweak to tidy up that particular line - I'm thinking I'd like to just be able to say:
  val captor = ArgumentCaptor.for[List[String]]


Stay tuned ...

Tuesday, 29 October 2013

Characteristic Impedance Mismatches

I'm going old-skool on this one - I've got tabular data, I'm gonna use a table, dammit!
You can have this... But not at the same time as this
Yearly IT Budgets Agile Project Development
"We're In The Cloud" Actually Being In The Cloud
Continuous Delivery Change Review Boards
Continuous Improvement Change Review Boards
Clean, Elegant, Responsive web pages Internet Explorer Support

Got any more?

Monday, 30 September 2013

Reflecting on Impedance Mismatches

I've been playing around a bit with MongoDB, and in particular its ReactiveMongo non-blocking asynchronous client for Scala. It's fitting in beautifully with what I'm trying to do with it (which is basically a standard CRUD webapp where the primary object in the domain model is some anonymous, arbitrary JSON block), even more so when I brought in the Play ReactiveMongo plugin.

Now I feel I'm really "living the dream"; I can concentrate entirely on my Scala code, sequencing in database fetches and stores when I want them, and not having to worry about the efficiency of table joins (never mind the tedium of getting them even working in the first place!) or mapping column types. The oft-mentioned "SQL-to-OO impedance mismatch" is gone, but even better, the ORM-to-useful code mismatch (which probably gives more pain in the long haul) is gone too.

Which got me to thinking - where are some other impedance mismatches in modern software development, and can they be eliminated as nicely?

Tuesday, 6 August 2013

The elusive single FakeApplication specs2 test

As has been noted in numerous places, the Play 2 documentation on testing kinda suggests that spinning up a FakeApplication is something you can/should do in every single one of your test examples, e.g.:

  // Don't do this
class MyControllerSpec extends Specification {

  "My controller" should {

    "return a 404 on top-level GET to non-existent resource" in {
       running(FakeApplication()) {
         val home = route(FakeRequest(GET, "/mycontroller/blurg")).get
         status(home) must equalTo(NOT_FOUND)
       }
     }

     "serve up JSON on list request" in {
       running(FakeApplication()) {
         val home = route(FakeRequest(GET, "/mycontroller/list")).get
         status(home) must equalTo(OK)
         contentType(home) must beSome.which(_ == "application/json")
       }
     }
  }
}
Trust me when I say that it is not a good idea. At the very least slow tests, inconsistent test results and general Weird Things™ will happen.

What you most-likely want is something like this:
import play.api._
import play.api.test._
import org.specs2.specification._
import org.specs2.mutable._

/**
 * Mix this in to your Specification to spin up exactly one Play FakeApplication
 * that will be shut down after the last example has been run.
 * Override 'theApp' to use a customised FakeApplication
 */
trait FakePlayApplication {
  this: Specification =>

  def theApp = FakeApplication()

  def startApp = {
    System.err.println(s"Starting $theApp")
    Play.start(theApp)
  }

  def stopApp = {
    System.err.println(s"Stopping $theApp")
    Play.stop()
  }

  override def map(fs: => Fragments) = Step(startApp) ^ fs ^ Step(stopApp)
}

Which you could use in my previous example as follows:

class MyControllerSpec extends Specification with FakePlayApplication {

  "My controller" should {

    "return a 404 on top-level GET to non-existent resource" in {
         val home = route(FakeRequest(GET, "/mycontroller/blurg")).get
         status(home) must equalTo(NOT_FOUND)
     }

     "serve up JSON on list request" in {
         val home = route(FakeRequest(GET, "/mycontroller/list")).get
         status(home) must equalTo(OK)
         contentType(home) must beSome.which(_ == "application/json")
     }
  }
}
Less repetition, faster execution, and most importantly, RELIABLE TESTS!