Monday, April 2, 2012

Redis exception: Cannot use Jedis when in Multi.

Jedis newbie problem when adding transactions to Redis client application:


Cannot use Jedis when in Multi. Please use JedisTransaction instead.
redis.clients.jedis.exceptions.JedisDataException: Cannot use Jedis when in Multi. Please use JedisTransaction instead.
 at redis.clients.jedis.BinaryJedis.checkIsInMulti(BinaryJedis.java:1651)
 at redis.clients.jedis.Jedis.hmset(Jedis.java:724)
 at test.TestService.updateSomething(TestService.groovy:39)
 at test.TestService$_processBet_closure1.doCall(TestService.groovy:16)
 at grails.plugin.redis.RedisService.withRedis(RedisService.groovy:67)

Description of exception is absolutely correct though a little confusing. Problem is that you are trying to call methods on Redis connection object instead of Transaction object. So most probably you have something like:


  Jedis jedis = pool.getResource()
  jedis.watch('foo')
  ...
  def transaction = jedis.multi()
  jedis.set("foo", value.toString())
  def result = transaction.exec()


But instead, you should have something like:


  Jedis jedis = pool.getResource()
  jedis.watch('foo')
  ...
  def transaction = jedis.multi()
  transaction.set("foo", value.toString())
  def result = transaction.exec()


Friday, March 30, 2012

Code snippet for JMS queue reader

There is quick snippet how to read from ActiveMQ queue with Groovy:


import org.apache.activemq.pool.PooledConnectionFactory
import javax.jms.Connection
import javax.jms.Session
import org.apache.activemq.command.ActiveMQQueue
import javax.jms.MessageConsumer
import org.springframework.jms.listener.adapter.MessageListenerAdapter
import javax.jms.Message

  PooledConnectionFactory pooledConnectionFactory
  ActiveMQQueue testJmsQueue

  pooledConnectionFactory.start()
  Connection conn = pooledConnectionFactory.createConnection()
  Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE)
  MessageConsumer consumer = session.createConsumer(testJmsQueue)
  consumer.setMessageListener(new MessageListenerAdapter() {
    @Override
    void onMessage(Message message) {
      println message.getContentMap()
    }
  })
  conn.start()


Thursday, March 22, 2012

How to read IMAP email with Groovy

There is quick snippet how to read email from Google IMAP with Groovy:

@Grab(group='javax.mail', module='mail', version='1.4')

import javax.mail.*
import java.util.Properties

def session = Session.getDefaultInstance(new Properties(["mail.store.protocol":"imaps", "mail.imaps.host":"imap.gmail.com", "mail.imaps.port":"993"]),null)
def store = session.getStore("imaps")
store.connect('imap.gmail.com', 'test@gmail.com', 'pass')
def folder = store.getFolder("INBOX")
folder.open(Folder.READ_WRITE)
folder.messages.each { msg ->
  println msg.content
}


Friday, March 16, 2012

JavaScript unit testing in Grails

Recently I wanted to test some complicated JavaScript code and surprisingly there is no a lot of options to choose from in Grails. Fortunately, I was already using Geb and it is extremely easy in this case.
I decided to use QUnit testing framework and all that needs to be done in this case is to place few static files in JS, CSS and HTML folders, create Geb page for QUnit reports and Geb Spec for launching browser. For development everything can be done (and much faster) with QUnit alone. Geb is basically only needed to run tests from CI (Jenkins in my case).


There is my Geb Spec:

package my.test.specs

import spock.lang.Stepwise
import my.test.pages.QUnitPage

@Stepwise
class QUnitSpec extends GebScreenshotsSpec {

  def "run QUnit tests"() {
    when:
    to QUnitPage

    then:
    at QUnitPage
    failedCount == '0'
  }

}


Geb page:

package my.test.pages

import geb.Page

class QUnitPage extends Page {
  static url = "http://localhost:"+System.getProperty("server.port", "8080")+"/my-test/js/tests/qunit.html"

  static at = { $("#qunit-header") }

  static content = {
    failedCount(wait:true) {$('#qunit-testresult .failed').text()}
  }
}


qunit.html and all it's content is just plain QUnit framework.

Disadvantages are that reports are not persisted or summarized with other testing frameworks, but if you have screenshots in your Geb tests, it will provide some feedback. Another issue is if you are not using Geb, than this can be overkill to use it only for JS unit tests.
But in case you already have Geb this is super-simple and lightweight approach.

Tuesday, March 13, 2012

Spock tests modularization

It is not very clear from Spock documentation how to split Spock feature methods into multiple functions. But, for example, Geb test scenarios sometimes can be quite complicated (if you want to verify something across multiple pages) and worth extracting into multiple methods for clarity and reuse.
In practice, this is very simple and all you have to do is just extract method and define Java style asserts as it is in Spock documentation about helper classes. What is not in documentation, is that you can freely mix actions with validation in same method, so for example, you can do something like this:

def "do something"() {
  when:
  someLink.click()

  then:
  validateEverything()
}
def validateEverything() {
  menuLink1.click()
  assert text1 == 'some text'
  menuLink2.click()
  assert text2 == 'other text'
}

At least this works fine with Geb.

Tuesday, February 21, 2012

Grails nullable boolean and integer fields

When your GORM domain object fields are defined as Java primitives like boolean it can only be specific value like true or false. But sometimes you may want to have also third value for undefined values or NULL as in database. With primitives you will get error like:
Executing action [edit] of controller [com.test.TestController] caused exception: Null value was assigned to a property of primitive type setter of com.test.TestObject.testproperty; nested exception is org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of com.test.TestObject.testproperty

To enable nulls for such fields, you just have to change type from boolean primitive to Boolean object and that is it.

Thursday, February 16, 2012

sprintf, printf bug in Groovy

Recently I found strange issue when running Grails application on Linux. Sometimes, when formatting decimal number with sprintf it does not work and simply returned original number. After some investigation I found that this is general Groovy behavior and simple script with:

println sprintf('%.2f', 1/609)

returns 0.0016420361 as result, when it suppose to return just 0.00. I was not able to reproduce this bug on Windows or in plain Java, so most probably this is GDK issue, but I didn't investigated it very carefully.
Anyway, this is very easy to fix by casting numbers into decimals explicitly, so this code:

println sprintf('%.2f', 1d/609)

returns nice and correct results.