Unit Testing in Adobe/Day/CQ5

There are a two approaches to effectively test your code in CQ5 – either outside of CQ5 using standard unit tests instantiated from your build tool (i.e. maven). While this approach will cover most simple functionality, the need will quickly arise to execute unit tests within CQ5/Sling/OSGi.

Testing outside of CQ5

In addition to your standard junit tests, you can grab a hold of the CRX repository and start writing some basic tests against that. As you can see in the following example, you ca even wrap the JCR-repository in its Sling equivalent:

package com.jtoee.cq.test;

import org.a~pache.jackrabbit.commons.JcrUtils;
import org.apache.sling.jcr.api.SlingRepository;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.Repository;
import javax.jcr.RepositoryException;

public class SimpleTest {
    private Logger log = LoggerFactory.getLogger(SimpleTest.class);

    @Test
    public void runTest() {
        try {
            log.debug("Connecting to respository");
            Repository repository = JcrUtils.
                    getRepository("http://localhost:4502/crx/server");
            SlingRepository slingRepo =
                    new RepositoryUtil.RepositoryWrapper(repository);
            log.debug("Retrieved sling repository");
            // .. do something
        } catch (RepositoryException e) {
            log.debug("Exception retrieving repository.", e);
        }
    }
}

Testing within CQ5

If you’ve dug into CQ5 a little more, you’ve noticed the the power of the OSGi container and have probably started writing a lot of components (services) and wired them together via dependency injection. Luckily there’s a very easy way to run unit tests directly in the container and even use the OSGi-style dependency injection directly in your test, allowing you not only to write simple unit tests but also more involved automated integration tests.

According to the Apache Sling testing guideline there are a few approaches but I shall only focus on one of them today.

First, we will need to install a new Sling Junit OSGi bundle into Felix (http://localhost:4502/system/console). Grab it via subversion and compile it:

$ svn co http://svn.apache.org/repos/asf/sling/trunk/testing/junit/core

$ cd core

$ mvn package

Then go into the Felix console (Install/Update button on the right) and install the resulting jar file as a new component (it’s in core/target/org.apache.sling.junit.core-1.0.7-SNAPSHOT.jar):

Now you’re ready to write your first test into one of your custom OSGi bundles. One thing to keep in mind is that while with regular unit tests you would write your tests in the src/test/java directory structure (assuming a standard Maven project layout), you would put these tests into the src/main/java directory – you want them deployed and executed as part of the bundle.

Let’s take a look at a first test:

/**
 * <p/>
 * User: jochen
 * Date: 9/24/11
 * Time: 9:08 PM
 */
@RunWith(SlingAnnotationsTestRunner.class)
public class MyAwesomeTest {

    @TestReference
    private BundleContext bundleContext;

    @TestReference
    private SlingRepository repository;

    @TestReference
    private ResourceResolverFactory resourceResolverFactory;

    @TestReference
    private CloudStorageService storage;

    /**
     * Get a sling resource resolver
     */
    public ResourceResolver getResourceResolver() {
        try {
            return getResourceResolverFactory().
                    getAdministrativeResourceResolver(null);
        } catch (LoginException e) {
            fail(e.toString());
        }
        return null;
    }

    @Test
    public void testCreateFutureAttachment()
            throws Exception {
        assertTrue(true);
    }
}

As you can see with the class annotation @RunWith(SlingAnnotationsTestRunner.class) we’re telling the system to automatically inject OSGi-dependencies into the test case (you can’t use the regular @Reference annotations you might be using in the rest of your code since these have a compile-time retention policy). Use the @TestReference annotations to inject any of your defined components into your test. The rest of the test is standard Junit.

Maven Setup

Before running the tests, you need to register a regex for the test runner to identify your tests by name, such as the following Maven example does:

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <extensions>true</extensions>
  <configuration>
    <instructions>
        <Export-Package>
            com.jtoee.cq.test.*
        </Export-Package>
        <Sling-Test-Regexp>.*Test</Sling-Test-Regexp>
        <Private-Package></Private-Package>
        <Import-Package>
   ...

Running Your Tests

The Sling unit testing core package installed earlier includes a simple servlet runner which is available via http://localhost:4502/system/sling/junit/ (adjust to your particular installation). You can simply run the tests from there. The runner implements various selectors, namely .html, .xml, and .json. Especially the XML-based format lends itself toward an easy integration into an automated build process:

$ curl -X POST http://localhost/system/sling/junit/com.jtoee.cq.xml

While I’ve come to love using the the JSON format via curl for readability, it doesn’t give you the stack traces in case any of your tests fail. However, the XML format does.

Conclusion

You have no more excuse not to write unit tests.

Agile – Keep It Simple

Being hip followers at work, almost all of our projects are agile now. But while have a solid agile process defined which works well across disciplines and time zones (i.e. off-shore), just peeking in on various projects every now and then makes me wonder why I see the same problems pop up again and again.

First of all, agile is actually a very simple, disciplined process — and that’s the beauty of it. It’s simple. Plan out your work, track it, create a workable/releasable piece of software with every increment, do a demo, regroup, repeat. A simple process built on simple principles of sustainable development (that means not burning your teams out, dummy).

So what are some of the things that I keep seeing that are messing with the success?

1. Keep re-planning throughout the sprint

Constantly re-prioritizing every day and letting the clients and other sprint teams (e.g. user experience/functional folks) influence the core development team. This is a major no-no. The idea is that at the beginning of the sprint you plan out your work together with the product stakeholder. You do not add or change work or the major goals of the sprint during the sprint. If the sprint plan needs to be changed, interrupt the sprint and call for a planning meeting. It seems to be tempting to squeeze a little this and a little that into a sprint, but in the end it compromises the quality of the increment’s deliverable. And usually causes  long hours for the dev team.

Here’s another awesome idea. Invite many managers to every meeting (yes, they exist in most organizations) and have them talk, create chaos, then leave for a few weeks just to come back and change direction.

Remember – agile teams are to be self-organizing and interact with their product owner for direction during sprint planning. The key is really in the self-organizing part. Empower your team.

2. More features

You want to impress the client and add more and more features into the sprint and think it’s perfectly ok to implement each of them half of the way as long as you have something to show for. Well, remember that one principle of agile development? Workable software with every increment. Having a bunch of half-implemented features not only creates half-assed non-releasable software, but also causes your features to bleed into the next sprint where your team will spend half the sprint cleaning up the features from the previous one. And of course your client won’t be happy because the sprint demo probably won’t go well. Your developers will hate you for the long hours trying to just get something to work even though they probably have to rip half the code out again in the next sprint.

Time savings? No.

Increased productivity? No.

Happy clients? Probably not.

3. Who’s the scrum master?

Appoint a non-technical person to be the scrum master of your tech team. This might be a little controversial, but I don’t think that project managers without tech background make good scrum masters for a technology team. The scrum master should be the equivalent of the technology lead for the team. This is especially important in a multi-team environment like we have at an agency or any other sizeable project. The lead of the team needs to be able to participate in scrum-of-scrum meetings with the other teams and be able to fully understand the technology as well as any implications of decisions the other teams are making. So the scrum master of the technology team needs to be able to coordinate between the user experience / functional scrum team and the technology team. Otherwise you’re headed into disaster with two interdependent scrum teams which are running into opposite directions. And you need scrum-of-scrum meetings to coordinate in a multi-team environment; don’t think you can save those 10 minutes a day.

4. Code away

Write no documentation. Yes, agile processes are light on documentation. But that doesn’t mean that you don’t document and just code away. That’s the cowboy methodology. You still have to document what needs to be documented. Just create a task for the documentation during your planning session. Documentation isn’t all bad, just keep it to the necessary amount. API specs of interfaces your provide to another scrum team would be a great idea to document, so are core data models of your application so you don’t have to repeat the same discussion with the team all over every two days. Use a wiki.

5. Standups

Sit down and talk through all the issues for an hour every day during your standup meeting (I guess that would make it a sit-down). Really, keep them short and simple, all major discussion should be happening outside of these meetings. Limit them to 10-15 minutes, talk about your accomplishments, what you’re about to do, and your impediments. You might be able to just get by with talking about impediments, but that depends on your team. These meetings are not meant to waste time and make managers happy. If you’re having a hard time with this one, pass around an egg timer that goes off after a minute or two of talking.

 

Alright. That’s five for starters. So please keep agile simple. I know it’s not easy, but resist the dark side.

Certification Incompetence

Most of my friends and colleagues are very negative about certification schemes in software development, a disdain that I share. This doesn’t mean that I think that certifications in software are bad by definition, just that almost every one we see fails a basic test.

Couldn’t agree more, Mr. Fowler. Read on..

Bye Bye Holographic Storage

I remember reading this great article about holographic storage in 1991. Yes, that’s 1991, I was a nerd even back then (article on Der Spiegel or via Google Translate). Holographic storage was going to take over everything and replace hard-drives in five years. I guess that didn’t happen, but companies such as InPhase sure kept trying. Now according to ZDNet, InPhase finally bit the dust.

Bye bye holographic storage, too bad we never met, but you sure sounded like a cool idea.

Ditch Flash, Mr. Jobs. Really?

Apparently Steve Jobs told the Wall Street Journal to ditch flash because it is a buggy old technology with security holes. That’s an interesting attitude, considering that the real reason for why Apple refuses to support Flash on the iPhone and iPad is that it would undermine the Apple store and they would have to relinquish their total control over what apps run on the devices. That and the fact that AT&T would have to deal with large-scale video streaming on their network (here’s interesting article regarding this on the Economist).

Do no evil, Mr Gates Jobs and let us decide what software to install on the devices.

Link: Game Development in a Post-Agile World

I ran across this totally awesome rant/statement of facts (thanks Slashdot) about real-world development, hype, and just getting things done. I personally have always been a huge proponent of just doing what works and feels right in the particular situation, borrowing bits and pieces from all kinds of methodologies. I’ve never been a fan of folks who want to follow a process (whichever it is) on a text-book level.

While the author talks about projects in the gaming world, I think these translate 1-1 to my reality. I think I would like to have a drink with the author of this post. Read it here.

Launching Open Source Home Automation Site!

Taking my home automation tinkering to the next level, I am launching catrpillr.com as an open-source solution to home automation. The site contains circuits, software, firmware, and documentation. Be advised that you currently still need at least intermediate knowledge of electronics to put these pieces together. The current solution allows you to fairly easily link together devices through low-cost radio-frequency receivers and transmitters, a few sample circuits such as a generic binary sensor and a relay-based remote switch are included.

A lot of the Arduino and hardware-related posts as of late will start going over onto the new site, freeing this site back up for things relating to (enterprise) software development.

Read More >

Connecting Multiple AVR/Arduinos via I2C/TWI

Since my RF receivers require a full hardware-based UART to function reliably, I decided to opt for adding a simple attiny2313 as a controller connected to an Arduino. Ready to build a simple protocol, I decided to do a little more research into I2C — the inter-integrated-circuit protocol which puts multiple digital micro-controllers on a low-speed bus. As it turns out, the attiny controllers actually implement the full protocol, even if Atmel calls it TWI (two-wire-interface). The protocol defines a master device as well as up to 127 slave devices (7-bit addressing).

The hardware is very easy to hook up and it simply requires two wires (TWI is not just a clever name) – one called SDA, to transmit the data, and one called SCL, to transmit a clock signal. On an Arduino Duemilanove SDA is analog pin 4 and SCL is analog pin 5. On the attiny2313 controller, SDA is pin B5 (pin 17, also MOSI), and SCL is on pin B7 (pin 19) — also refer to Alex’s cheat sheet for the pins. Just connect SDA to SDA and SCL to SCL.

Arduinos have the Wire library built straight into them, and after some hunting I found a small library for atttiny adapted from the original Atmel code by a Donald Blake (can be found on avrfreaks.net or my subversion repository). The Arduino is quickly configured as a master and set up to send and receive characters typed into the serial console to and from the slave controller:

// Arduino Code
void
  setup()   {
  Serial.begin(57600);
  // initialize as i2c master
  Wire.begin();
  Serial.println("OK>");
}
// loop forever..
void loop()
{
  // data available from computer?
  if (Serial.available()) {
    // read the incoming byte from the serial port
    sByte = Serial.read();
    // begin transmission to device 1    
    Wire.beginTransmission(1);
    // send
    Wire.send(sByte);
    // done
    Wire.endTransmission();

    // request data from device 1
    Wire.requestFrom(1,1);
    // echo out whatever we get back
    while(Wire.available()) {
      Serial.print(Wire.receive());
      Serial.print("-");
    }
  }
  delay(100);
}

On the slave, simply link the Donald Blake’s library into the code and this then does all the magic:

// attiny2313 code
int main(void)
{
  // initialize as slave with id 1
  usiTwiSlaveInit(1);

  // enable interrupts (must be there, i2c needs them!)
  sei();

  // handle commands
  while (1)
  {
    // check if data is in the i2c receive buffer
    if(usiTwiDataInReceiveBuffer())
    {
      // get it
      uint8_t b = usiTwiReceiveByte();
      // echo it back
      usiTwiTransmitByte(b);
    }
    // Do something else while waiting for the TWI transceiver to complete.

    asm volatile ("NOP" ::);
  }
  return 0;
}

Works like a charm!

Atmega/Arduino (Soft-) Serial Ports

In the implementation of the “reverse” channel of my home automation system, the RF receiver will transmit radio data back to the master controller which in return sends it to the computer. Since the atmega168/328′s processors used in the standard Arduino only have one hardware-based serial port (UART), I tried for the software-based serial that ships with the Arduino IDEs. Transmitting data out works like a charm (as seen previously), but receiving it is quite a challenge, mostly due to timing problems. The software serial port doesn’t work unless all the sketch does is gather data — there’s no time for processing or it will start losing data.

My next attempt was to use an interrupt-based version of the software serial port. I briefly thought about writing one, but then I found this great libary, the New SoftSerial. It is as simple to use as the original library, but unfortunately once I connect the RF receiver, the processor is too busy handling interrupts and nothing really works. The noise picked up by the RF module must simply overwhelm it. That’s too bad, this works beautifully on my attiny2313-based receiver when using the hardware UART.

A software-based solution is clearly not the answer, some hardware is required. I can think of a few options

  1. Abandon the Arduino altogether and use an AVR controller with multiple UARTs — not ideal, I like the idea of basing the master on Arduino for the hackability factor
  2. Use a logic gate and an external clock generator to sample/filter the signal exactly at the right timing required for 1200 bps (the maximum reliable speed I could get to work for the RF modules) – this could still lead to timing issues
  3. Create an attiny2313-based “daughter-board” which handles all the nitty gritty of the RF communication using the hardware-UART and then communicates to the Arduino via a few of the regular digital ports (I’m thinking asynchronously via about 4 pins)

Clearly this requires a little more thinking, but I’m leaning towards the third option — it encapsulates all the protocol logic on the attiny’s and the Arduino library that would need to be written to communicate with it would be very light-weight. And let’s not forget the attiny’s are only about two bucks.

iPhone Garage Door Opener

You keep forgetting your keys but would never let your precious iPhone out of sight? Then nothing should seem more obvious than the need to open your garage door with your iPhone. An Arduino and a few microcontrollers, relays, rf link transmitters and receivers and some firmware later, it’s now reality. Check out the prototype (and excuse the slightly shaky video, it was bitter cold outside):

Read more about the setup and software here.

Next Page →

-->