Thoughts are free, who can guess them?
They flee by like nocturnal shadows.
No man can know them, no hunter can shoot them,
with powder and lead: Thoughts are free!
About www.weisserth.net
Tobias Weisserth
Hamburg, Germany
Software Enthusiast and CMS Fanatic

Java Pattern: try things repeatedly until reaching a timeout

Posted by polarapfel Thu, 26 Aug 2010 06:59:00 GMT

Nondeterministic tests are a common problem in test setups, especially with integration tests. For example, imagine you are doing an integration test of two components that exchange messages where receiving a message in one of the systems changes its internal state which you want to verify. However, the message exchange can be delayed due to external factors (network latency, load etc.). When running tests (for example using the excellent Cucumber framework), testing steps are usually run sequentially. It may happen that the tested system is lagging behind the testing steps, failing your test in some (but not all) cases. You need to make your tests more tolerant for these situations. Often, that means retrying for a couple of times.

How would you implement this pattern in Java? Well, here’s how I did it. I am using a timed runner object that tries an action until it succeeds before it times out. You can define what should happen in case the action times out, by overwriting the abstract method.

/**
 * Use this class to run actions with a timeout. 
 * Actions have to be wrapped within 
 * a yield method of the Yieldable
 * interface.
 */
public abstract class TimedRunner {
  
  private int timoutLength;
  private int elapsedTime;
  private int checkRate = 250;

  public TimedRunner(int length) {
    timoutLength = length;
    elapsedTime = 0;
  }

  public TimedRunner() {
    timoutLength = 10000;
    elapsedTime = 0;
  }

  public synchronized void reset() {
    elapsedTime = 0;
  }

  public void run(Yieldable runMe) {
    for (; ;) {
      try {
        Thread.sleep(checkRate);
      }
      catch (InterruptedException ioe) {
        continue;
      }

      boolean success = runMe.yield();

      elapsedTime += checkRate;

      if (success) {
        break;
      }

      if (elapsedTime > timoutLength) {
        timeout();
        break;
      }
    }
  }

  // just overwrite this method to perform the timeout action
  public abstract void timeout();
}


Now, in other languages, like Ruby or Python you could just call a method and pass it a block of instructions. As that’s not possible in Java, you need to wrap the actions you want to pass within a method belonging to an object you can pass along. That object will be an instance implementing the Yieldable interface:

/**
 * Implement this interface when you want 
 * to use TimedRunner. TimedRunner 
 * expects a Yieldable object, class its yield
 * method and calls it until 
 * it succeeds or a timeout is reached.
 */
public interface Yieldable {
  public boolean yield();
}


The yield() method needs to return a status of success or failure so that the TimedRunner knows when to stop calling it. You could extend/modify this pattern by changing the signature of yield() to match your specific needs.

What should be done in case of a timeout? The most common thing to do would be to fail the test (assuming usage of JUnit 4):

import junit.framework.Assert;

public class FailRunner extends TimedRunner {
  @Override
  public void timeout() {
    Assert.fail("Timed out without success.");
  }

  public FailRunner(int timeout) {
    super(timeout);    
  }
}


In your test code, you would put the nondeterministic code within a yield method and pass it to a TimedRunner instance:

// ... within your test code...

Yieldable runMe = new Yieldable(){
  public boolean yield() {
    // do something here and return true 
    // if it succeeded or false otherwise
  }
};

new FailRunner(30000).run(runMe);

// ...


Feel free to leave feedback in the comments. I would be interested to learn how you handle testing issues such as this one.

Java, arrays, autoboxing and Arrays.asList

Posted by polarapfel Thu, 06 May 2010 16:54:00 GMT

Yesterday, I had some fun with Java again. Since Java 1.5 it has become so natural to mix primitive datatypes with their object based counter parts as Java boxes and unboxes expressions as necessary without the need to make any explicit casts – or so I thought. Take a look at the code below:

byte[] testBytes1 = {1, 2, 3, 4, 5};
List<Byte> list1 = Arrays.asList(testBytes1);


If you expected that you can create a list of Byte objects from a byte[] array, then you’re sadly mistaken. As Java cannot autobox arrays (which are backed up by a separate type, not equal to the respective primitive elements within), Arrays.asList will not accept testBytes1 since its type is byte[] which is not autoboxed into Byte[]. So above example code is not valid without changes.

It would compile like this:

byte[] testBytes1 = {1, 2, 3, 4, 5};
List<byte[]> list1 = Arrays.asList(testBytes1);


So, now you expect that you will end up with a list of five Byte objects? Wrong again. Look at the expression and its type. The type is still byte[]. So, list1 contains exactly one element, which is an array with five byte literals.

Long story, short answer: before using Arrays.asList loop over a primitive array and copy the elements to an object based array.

Using the MySQL encrypt function in Ruby

Posted by polarapfel Sun, 14 Feb 2010 17:48:00 GMT

If you’re dealing with a legacy MySQL database schema where your users’ passwords are encrypted using MySQL’s encrypt function within your schema and you want to create new records like that using Ruby rather than calling the MySQL function, you can easily do that with Ruby. Ruby supplies a crypt function that does just what the MySQL encrypt function provides. Both implementations use the UNIX C function crypt(3) so you can replace the use of one with another.

The function expects a salt value of two characters. If none is provided, a random string will be used. Take a look at this simple example:

  #!/usr/bin/env ruby -wKU

  def mysql_encrypt(pw)
    
    # compute a random salt value
    # (will end up to be a Base64 encoded string 
    # of random characters)
    salt = [Array.new(2){rand(256).chr}.join].pack("m").chomp
    return pw.crypt(salt)
  end

  encrypted_password = mysql_encrypt("test")

  puts "Encrypted password could be " + encrypted_password

  # we take the first two characters of the already
  # encrypted password as salt value
  # for the re-encryption so we end up with the same value
  
  compared_password = "test".crypt(encrypted_password[0,2])

  puts "The re-encrypted 'test' string is now " + compared_password

Creating hashed passwords using crypt(3) cannot be regarded as secure though. Take a look at the Wikipedia entry on crypt. If you’re implementing any kind of user authentication from scratch, consider using other means of hashing passwords.