clone a postgresql database for testing cleanly

I’m looking at writing integration tests for the back end of JavaRanch‘s JForum install.

A few “pesky” requirements/constraints

  • Multiple developers all over the word have their own local test databases filled with data in different states.  The tests must work for everyone.  Ideally they won’t leave data floating around either.
  • The tests must use PostgreSQL.  While the original JForum supported multiple databases, the JavaRanch version has been scaled down to just run with the one we need.  We do have some PostgreSQL specific SQL which rules out using an embedded database like HSQLDB or Derby.
  • Developers are using both Eclipse and IntelliJ.  Tests should care about the IDE anyway, so this isn’t a big constraint.
  • Developers are using a variety of operating systems and languages on their operating systems.  While code is in English, there can’t be assumptions as to the OS state.

Strategy

I think the best strategy is to create a second database just for testing.  The JForum database would remain untouched and a jforum_integration_test database can be created for the tests.  dbUnit can control the state of that special database.

The problem

Before I even start thinking about dbUnit, I did a proof of concept to ensure I could create a new database from scratch using the command line.  Creating a database is the easy part.  The “hard” part is that JForum doesn’t come with a schema.  It comes with an installation servlet that creates the schema.  While few people will be creating a schema for JForum, the technique I used applies elsewhere.

The procedure “before”

  1. Start up the JForum war
  2. Go to the JForum install URL and enter some information which creates the tables
  3. Run the JavaRanch customizations.

How to clone a database for which you only have a partial script

  1. Create an empty database
    createdb jforum_integration_test
  2. Arrive at the base schema
    1. Go the JForum installation URL
    2. Enter the information to create the tables
  3. Export the schema thus far
    pg_dump -U postgres jforum_integration_test > c:\temp\postgres.sql
  4. Provide instructions for the rest of the sql which were created by our developers.

How to import

Now for the easy part!

Importing this dump is a matter of a single command:

psql -U postgres jforum < "pathToWorkspace\JForum\javaranch-docs\deployment\file.ddl"

Lessons learned after

The next day I learned that this wasn’t enough.  We also needed some test data from the server.  I ran this a few times to get the relevant test data.

pg_dump --data-only --inserts -U user -W database --file roles  --table tableName

Conclusion

My next step will be to actually configure dbUnit against this new database and start writing tests.

Solution to Flex Image Rotation and Flipping around Center

Today, I was trying to rotate and flip an image around its center point in Flex and the solutions I came across on the web didn’t seem to do the trick. For images that have been previously dragged/dropped, resized, rotated, or translated, the existing solutions are simply not sufficient. With that in mind, I’ve written a solution for rotating and flipping an image around its center that works perfectly in all situations.

The Code

Without further ado, here’s the solution:

private static function rotateImage(image:Image, degrees:Number):void {
	// Calculate rotation and offsets
	var radians:Number = degrees * (Math.PI / 180.0);
	var offsetWidth:Number = image.contentWidth/2.0;
	var offsetHeight:Number =  image.contentHeight/2.0;

	// Perform rotation
	var matrix:Matrix = new Matrix();
	matrix.translate(-offsetWidth, -offsetHeight);
	matrix.rotate(radians);
	matrix.translate(+offsetWidth, +offsetHeight);
	matrix.concat(image.transform.matrix);
	image.transform.matrix = matrix;	
}

Also, here’s a related function to perform a horizontal (left to right) flip of an image:

private static function flipImage(image:Image):void {
	// Calculate offset
	var offsetWidth:Number = image.contentWidth/2.0;
	var offsetHeight:Number =  image.contentHeight/2.0;

	// Perform horizontal flip
	var matrix:Matrix = new Matrix();
	matrix.translate(-offsetWidth, -offsetHeight);
	matrix.scale(-1, 1);  // change to matrix.scale(1,-1) for vertical flip
	matrix.translate(+offsetWidth, +offsetHeight);
	matrix.concat(image.transform.matrix);
	image.transform.matrix = matrix;
}

The Problem Explained

The problem, in a nutshell, is that Flex maintains the top left corner of the image for all transformation and ignores the center point. For example, just calling the rotate() method will produce rotations around the corner such as in this example. Many almost-solutions, see here and here, resolve this by first moving (translating) the image around its center by using the image’s vertical and horizontal midpoint.

A more complex issue arises, though, when the image is no longer positioned at its anchor, or in technical speak the image’s transformation tx/ty values are not 0. I found once you sufficiently drag/drop, rotate, or otherwise modify the image, all of the solutions tend to fall apart. In my situation, all the images were oriented with tx/ty referring to the anchor of the canvas, making these previous solutions difficult to rely upon.

The Solution Explained

After some fun manipulating matrices, I’ve written and tested a solution that will properly rotate an existing image around its center regardless of where it is positioned on the canvas or what transformations have been performed on it. It starts by applying rotation around the image’s center to the identity matrix. In this way, it simulates rotating the matrix around its midpoint translated position, but it is actually applied to the identity matrix. Once the rotational matrix has been calculated, the image is stuck at the top of the canvas. What we really need is a matrix that will take the rotational matrix we’ve just calculated and apply all the previous transformations to orient/rotate the image in the proper position. Well it so happens we have such a matrix, the image’s transformation matrix in fact! So, we apply the transformation matrix of the image to our calculated rotational matrix and voila! The result is our transformed image rotated by the specified amount around its center. We just set the image’s transformation matrix to this result and we are done.

algorithms – survival of the fittest

I’ve been volunteering with a FIRST robotics high school team as a programming mentor. Due to a “series of unfortunate events”, we didn’t get to test our logic to drive straight in autonomous mode until the night the robot went into the crate.

We wound up using an interesting approach. First we brainstormed options and prioritized them. If the programmers got the robot early, we would test in that order. Alas, we did not get the robot early. We got it for 45 minutes about an hour before packing time.

Since it takes time to load code changes to the robot, we parallelized as much as possible. The students had time to test the competing approaches before we got our turn with the robot. So we tried them all by flipping a switch and then tuned the most promising one. It was a great use of time and available resources. And we wound up with an approach that wasn’t in our initial brainstorm.

The lesson applies to us all. Be aware of your primary constraint; in this case time; and optimize to that. Punch card programmers certainly knew this and optimized per run at the machine.

I was very impressed. Good luck in the regional competition team 694!