All Under One Roof.

vikings-stadium-topping-2I live in the western part of Minneapolis metro area, and I don’t often head to the eastern part of our fair city.  Because of this, I am often struck by things that have been added/changed in the time since my last visit.  Like…  the huge new sports stadium on the eastern side of downtown Minneapolis.  I am not going to comment (much) on building such giant structures with public money.  Regardless of what you think about such things, it is hard not to be impressed with the size and rate at which the new stadium was built.

Having the ability to bring things up and down quickly as we develop software applications is a tremendous advancement in the past several years.  Containers and Docker provide us with excellent tools to test and even deploy applications without worrying about specific concerns of hardware, or with dealing with the old-day concerns of giant virtual machine sizes.  Check out the tutorials on the Docker site, if you are interested in more details.  Inside that fancy new stadium, you will quickly notice this…

071616-n-mcb-stadiumminnesota01

The new Vikings (or should I say  US Bank) Stadium Jumbotron.  Being that I like to build things, I decided to try and build my own…  but on a much smaller scale.  I give you the “minitron”…

img_3381-2And, yes, that is a small part of an “S” scrolling by on the screen.  The idea for this little guy goes beyond just the “charlieplexed” LED display and an Arduino Uno.  There is also a SparkFun ESP8266 module involved and, of course, a nice little Heroku app backing it.  The goal of the project is to create more of these little minitrons, and allow them to call back into the Heroku app to pick up messages to display.  This is all fronted by a web application that allows users to log in, register their own minitron (each one comes with its own preset device code) and enter in up to 16 different messages that can scroll by on the screen.  The user can also custom-draw a 9×16 pixel image that will be displayed on the screen too.

So, how do we go about building this kind of thing?  Lets start with the web application.

I have written a very simple Springboot 1.4 application that will be hosted on Heroku…  because it is free.  I am storing the data in Postgres (because that is a no-brainer when dealing with Heroku.)  I will post more about the hardware and Arduino code later, but for now, let’s start with some thoughts regarding testing.

If you have read any of my previous blog posts, you know that I am a pretty big fan of TDD.  Let’s briefly touch on the different kinds of tests that I have been working on; DAO, Service, and Integration tests.  I will also mention a few words about using docker for test dependencies.

DAO Tests

As with most web-apps, the minitron web app needs to access a data repository.  In this case, that repository is Postgres.  There are a number of ways to accomplish this with spring.  For the case of the minitron app, I have decided to go with a pretty basic implementation of JDBC for accessing the data because the data store will only have 3 tables, and the object to relation mapping is extremely simple.  In order to access the database, I will be using preparedStatements.  This provides me with an excellent opportunity to test those classes.  Here is a sample test:

class DeviceDaoSpec extends Specification{

    DeviceDao deviceDao
    Connection connection

    def setup() {
        deviceDao = new DeviceDao()
        connection = Mock(Connection)
        deviceDao.conn = connection
    }

    def 'I should be able to save a device'() {
        given:
        UUID deviceId = UUID.randomUUID()
        UUID userId = UUID.randomUUID()
        Device device = new Device(userId: userId, deviceCode: "xyz123", deviceId: deviceId)
        PreparedStatement preparedStatement = Mock(PreparedStatement)

        when:
        deviceDao.save(device)

        then:
        1 * connection.prepareStatement("insert into device (deviceCode, deviceId, userId) values (?,?,?)") >> preparedStatement
        1 * preparedStatement.setString(1,"xyz123")
        1 * preparedStatement.setString(2, deviceId.toString())
        1 * preparedStatement.setString(3, userId.toString())
        1 * preparedStatement.execute()
        0 * _
    }

Clearly, this is a Spock test.  (http://spockframework.org/spock/docs/1.1-rc-3/index.html)  I have recently been using Spock more and more for unit testing.  (Which is what this test is) because of the great built-in mocking features included with Spock.  Note that the test follows the standard “Given, When, Then” format, making it painfully easy to read.  A quick note about the 1 * and 0 * stuff included in the then section…  for lines with a 1 *, the test will assert that that statement gets called only one.  The 0 * _ asserts that nothing else gets called.  I really find this useful when testing these types of systems.  It is very easy to test that something subsequent thing happens when you call a method.  Testing that nothing else did, can be a bit more tricky…  the 0 * _ feature of Spock mocks make this much easier.

Service Tests

The service layer tests for the application mirror pretty much the DAO layer, except that rather than confirming that we are generating the expected prepared statements, in the DAO layer we are testing slightly higher level business logic.  In the minitron application, there is a pretty close matching between the Service and DAO level tests and methods.

Integration Tests

Integration testing gets a bit more interesting.  I could, and maybe should, write tests for the individual controllers, and mock out the behavior of the underlying service layer.  I decided to skip those tests for now, as the same code will end up being tested with a full-blown integration test.  Those integration tests will us RESTClient to send data to the controllers via the running application, and assert on expected data returned…  and possibly on the presence, or lack of data in the underlying database.  I initially started working on this with the database actually running locally.  That is not a bad approach, and gives us the ability to move quickly.  However, it is not the greatest approach either in the sense that we now have to worry about cleaning and restoring the database as part of the test framework.  Also, we will require any subsequent system that wishes to run the tests (other developers, or CI/CD servers) to run those dependencies as well.  Enter Docker….

Docker

To solve the problem of having a dependent system database system up and running, I have decided to create an annotation that I can use with my springboot integration tests that will bring up and initialize a Postgres database (with the appropriate users, tables, etc) inside of a docker container.  Stay tuned to my next blog post for more details on those steps.

In the meantime…  get out and enjoy the wonderful weather this weekend.  Who says we need an enclosed stadium in Minneapolis, anyway?!

Note:  as this project continues, please feel free to check out the public GIT repo:

https://github.com/fractalbass/minitron

 

Advertisements

Author: Miles Porter

Miles Porter is a senior consulting software engineer in the Minneapolis, MN. He is interested in pragmatic software development practices, embedded software, and cloud computing. In his free time he likes to travel with his family, play upright and electric basses and study Taekwondo.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s