Monday, July 23, 2007
Exposing the stereo knobs

As I mentioned in my last post, I'm about to implement an algorithm that involves a bunch of constant coefficients that we might be wanting to play around with. In order to make them easy to play with at runtime, we'll go the JMX route.

First, the service code will just have the coefficients injected as dependencies:

public class MagicalAlgorithmServiceImpl {
 protected int coefficientOne;
 protected int coefficientTwo;

 public void setCoefficientOne(int one) { ... }
 public void setCoefficientTwo(int two) { ... }

 public int performMagic() { ... }
}

Naturally, in the Spring application context, we'll create the bean like so, so it can be easily modified at build/startup time, using Maven resource filtering:

<bean id="magicalAlgorithmService" class="com.blogspot.codeartisan.magic.magicalAlgorithmServiceImpl">
 <property name="coefficientOne" value="${magic.coefficientOne}">
 <property name="coefficientTwo" value="${magic.coefficientTwo}">
</bean>

Now, we just need to define a management interface:

public interface MagicManager {
  public void setCoefficientOne(int one);
  public void setCoefficientTwo(int two);
}

Now, we make the MagicAlgorithmServiceImpl implement MagicManager.

Then if you've managed to get a JMX port exposed through your container (here's how to do it for Tomcat), all you need to do to expose this functionality via JMX is to use Spring's MBeanExporter:

<bean id="mbeanServer" class="java.lang.management.ManagementFactory" factory-method="getPlatformMBeanServer"/>

<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
  <property name="server" ref="mbeanServer"/>
  <property name="beans">
    <map>
      <entry key="MyApp:type=Twiddling,name=magicAlgorithm" value-ref="magicalAlgorithmService"/>
    </map>
  </property>
  <property name="assembler">
    <bean class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">
      <property name="interfaceMappings">
        <props>
          <prop key="Fancast:type=Twiddling,name=magicAlgorithm">com.blogspot.codeartisan.magic.MagicManager</prop>
        </props>
      </property>
    </bean>
  </property>
</bean>

That's it. Now you can twiddle with the stereo knobs at runtime via a JMX console.

Friday, July 20, 2007
Customer engagement

Where I work, we have a product group that functions as our product owners for Scrum development. Fortunately, they are co-located, which generally makes them pretty accessible for clarifications, although they do have this habit of having to be in a lot of meetings (hi guys).

So today I sat with one of them to work out a fairly complicated user-specific algorithm for sorting a bunch of movies and tv shows. In the end we came up with a scoring system involving a lot of constants as coefficients; the plan was to make those easily configurable so we could play with them.

I'm actually planning to take this a little step further than normal, and rather than just making them configurable from the Spring application context, I'm going to write an MBean that makes them configurable at run-time via jconsole. Then, I'm going to show the product guys how to play with the jconsole and let them come up with the actual coefficients we want to use while playing with a development instance.

I'm briefly debating handing out instructions to multiple executives so they can play too....

When I pick up again on Monday I'll post some basic code snippets.

Tuesday, July 17, 2007
Keep it Simple, Stupid

Well, I just spent a couple of hours last night trying to get the Cargo Maven2 plugin to work the way I wanted it to, which was to be able to control an already-installed local Tomcat by saying "mvn cargo:start" and then having that process exit.

Now the whole motivation was to try to get CruiseControl to redeploy the latest version of our webapp after a successful build. Due to various undeploy/deploy cycle PermGen memory leaks, and because it's on a shared server, I essentially wanted to just have CC do a "mvn cargo:undeploy cargo:stop cargo:deploy cargo:start". Unfortunately, it looked like this process would hang.

When I took a step back, I realized I could do that with a pretty short shell script, something like:

#!/bin/sh

# ... config variables here

curl --user $TOMCAT_ADMIN:$TOMCAT_PASSWD --url http://localhost:$TOMCAT_PORT/manager/html/undeploy?path=/
(cd $CATALINA_HOME; bin/shutdown.sh)
scp $MAVEN_REPO/webapp-1.2.3-SNAPSHOT.war $CATALINA_HOME/webapps/ROOT.war
(cd $CATALINA_HOME; bin/startup.sh)

Ok, a little more error checking, and you're basically done, and then just use an <exec> CC task conditionally off the normal continuous integration task.

Moral of the story: don't try too hard to do things in a fancy, snazzy way when a simple way works just fine. Incidentally, this is why some of my favorite phone screen questions to ask folks who are interviewing are (more or less):

  • what programming languages do you know/use?
  • do you know your way around a Unix command prompt?

If I didn't know enough Unix commands or shell scripting to do what I did above, I probably would have either given up or had to spend a ton more hours digging through the source code to the maven plugin to figure out why it wasn't doing what I wanted it to do.

Friday, July 13, 2007
Using interface hierarchies to enforce access protection

The "implements" relationship in Java between a class and its interface provides for Abstract Data Types where the client of the interface can't get at the guts of the implementation to muck around with it.

I recently encountered this where we had a user object that needed to behave differently based on different login states. We decided to use the State Design Pattern, where we would have the user object delegate to a state object for its state-specific behavior.

The way we initially set this up was to set up the User interface (one example here was that we needed to use a different user ID in different states):

public interface User {
  String getUserId();
}

public interface UserState {
  String getUserId(User u);
}

public class UserImpl implements User {
  private String emailAddress;
  private String sessionId;
  private UserState userState;
  public String getUserId() {
    return this.userState.getUserId(this);
  } 
}

Ok, great. Now, it turned out that the userId, depending on what state you were in, was either your sessionId, or it was a hash of your email address. This meant that the user states had to actually get at the emailAddress and sessionId of the UserImpl. Unfortunately, the argument of the getUserId(u) method in the UserState interface takes a User as an argument, and there's way to get the emailAddress of a User.

So we initially went down the road of adding getEmailAddress() and getSessionId() to the User interface, but that started clogging it up with a bunch of methods that the clients of Users would never need to use.

Eventually, we settled on a revised hiearchy:

public interface User {
  String getUserId();
}

public interface InternalUser extends User {
  String getEmailAddress();
  String getSessionId();
}

public interface UserState {
  String getUserId(InternalUser iu);
}

The implementation of UserImpl didn't actually change, but now we could still have the user object and its state interact via interfaces (side note: maybe in this case it would have been ok to pass a UserImpl as the argument of the UserState's getUserId(u) method, because this was so simple, but I've gotten really used to passing arguments and dependencies as interfaces). Also, the clients of the User interface were separated from having to know how the users were being implemented.

So: lesson for the day: if your interfaces are getting too bloated with methods, one place to look for refactoring is to try to break that interface into an inheritance hierarchy to simplify things.

Monday, July 9, 2007
TestUtil: package for unit testing setters/getters

In a comment on an earlier post, a reader Tatsu reported on the TestUtil package from the GTC Group that's a step ahead of us in this discussion. Here's a sample snippet of all you have to do to test the setters/getters of a Java class:

public void testSettersAndGetters() {
  assertTrue(TestUtil.verifyMutable(underTest, 1, 0));
}
where underTest is the instance of the class you are testing (created and injected in the setUp method of your JUnit). If someone has time, please dig in and let's understand what the 1 and 0 arguments are, and whether this is covering all the cases we've been talking about.

Thursday, July 5, 2007
Unit testing boolean setters and getters

It's crunchtime down on the ranch, so just a quick post today:

public class Foo {
  protected boolean theBool;
  public void setTheBool(boolean b) {
    theBool = b;
  }
  public boolean getTheBool() {
    return theBool;
  }
}
with:
public class TestFoo extends TestCase {
  private Foo foo;
  
  public void setUp() {
    foo = new Foo();
  }
  
  public void testSetsOwnTheBoolForSetTheBool() {
    foo.theBool = true;
    foo.setTheBool(true);
    assertEquals(true, foo.theBool);
    foo.theBool = true;
    foo.setTheBool(false);
    assertEquals(false, foo.theBool);
    foo.theBool = false;
    foo.setTheBool(true);
    assertEquals(true, foo.theBool);
    foo.theBool = false;
    foo.setTheBool(false);
    assertEquals(false, foo.theBool);
  }

  public void testReturnsOwnTheBoolForGetTheBool() {
    foo.theBool = true;
    assertEquals(true, foo.getTheBool());
    foo.theBool = false;
    assertEquals(false, foo.getTheBool());
  }
}
Again, this is in the context of creating an IDE command "insert-getter-setter-tests" which would take the property name (theBool), property type (boolean), and variable name of the class under test (foo) and generate the text for the two unit tests shown above. Did I miss anything for this one?

Tuesday, July 3, 2007
Unit testing setters and getters for Java base types

Yesterday we took a look at some "stock" unit tests for Java bean-style setters and getters, where the underlying property was an object. The tests for properties with base types will be similar, but slightly different. One nice thing about the object tests are that they can use the assertSame assertion (essentially that two objects are == each other) to make sure that the setters/getters do exactly what you thought they would. It's a little different with base types, because these must be compared by value and not by reference. For example, suppose we had implemented a setter for an integer like this (maybe as a stub):

protected int n;
public void setN(int newN) {
  /* no-op */;
}
Now, what if your unit test looked like this:
public void testSetsOwnNOnSetN() {
  int n = 0;
  underTest.setN(n);
  assertEquals(n, underTest.n);
}
It would pass (eek)! In the object cases, we were creating a new mock object and then making sure that object got put in there. Now, we can't necessarily tell. And there's always some chance that the setter is doing something funky, or that it got stubbed out with just the wrong value (incidentally, this is a good reason why it's better practice to throw an IllegalStateException("Not implemented") for an unimplemented method rather than just return something of the right type). So, I think the easy solution here is to use java.util.Random and generate a random non-zero value to use in the tests. Even better, generate two different values, and do:
underTest.n = rand1;
underTest.setN(rand2);
assertEquals(rand2, underTest.n);
Probably for a boolean you just want to exhaustively check the four cases of (previous_state, new_state). That's it for today. We'll be back on Thursday after the July 4th holiday, perhaps with a full-on listing of the unit tests for all the base types.

Monday, July 2, 2007
Unit testing setters and getters

So here's a question for the masses: is it worth it to unit test simple setters and getters? I would contend that if you can automatically generate the code for them, you can also automatically generate the unit test code that tests them (I smell a new ELisp command coming...). So what code should this tool actually generate? Here's my first cut, assuming we're going to use EasyMock: Let's say the name of the bean is foo, and it has class Foo (we'll go into unit testing beans of base type in a later post). Also, let's assume that the code for this in the production class (to distinguish it from the unit test class) looks as follows:

public class Production {
  protected Foo foo;
  public void setFoo(Foo foo) { this.foo = foo; }
  public Foo getFoo() { return this.foo; }
}
Note here that we made the foo field have protected scope, so that our test class (which we are assuming will be in the same package) can access it directly. I claim that these are the tests we need to write:
public class TestProduction extends TestCase {
  protected Foo mockFoo;
  private Production underTest;
  public void setUp() {
    mockFoo = EasyMock.createMock(Foo.class);
    underTest = new Production();
  }
  private void replayMocks() {
    EasyMock.replay(mockFoo);
  }
  private void verifyMocks() {
    EasyMock.verify(mockFoo);
  }
  public testSetsOwnFooForSetFoo() {
    replayMocks();
    underTest.setFoo(mockFoo);
    verifyMocks();
    assertSame(mockFoo, underTest.foo);
  }
  public testReturnsOwnFooForGetFoo() {
    underTest.foo = mockFoo;
    replayMocks();
    Foo result = underTest.getFoo();
    verifyMocks();
    assertSame(mockFoo, result);
  }
}
The replayMocks and verifyMocks are a habit I've developed, where I actually replay and verify all the mock objects in the test class, just to make sure I don't forget any. The use of these methods for these particular test cases actually asserts that there's no funny business going on here; none of the collaborators for the Production class are being called. So are there any cases this misses? What else would you want to test on your setters and getters? Tomorrow: what to do about base types.