views:

324

answers:

3

I'm trying to create integration tests using hsqldb in an in memory mode. At the moment, I have to start the hsqldb server from the command line before running the unit tests. I would like to be able to be able to control the hsqldb server from my integration tests. I can't seem to get this to all work out though from code.

Thanks, Casey

Update:

This appears to work along with having a hibernate.cfg.xml file in the classpath:

org.hsqldb.Server.main(new String[]{});

and in my hibernate.cfg.xml file:

<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
    <property name="connection.url">jdbc:hsqldb:mem:ww</property>
    <property name="connection.username">sa</property>
    <property name="connection.password"></property>
    <property name="connection.pool_size">1</property>
    <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
    <property name="current_session_context_class">thread</property>
    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
    <property name="hbm2ddl.auto">update</property>

Update It appears that this is only a problem when running the unit tests from within Eclipse using jUnit and the built in test runner. If I run

 mvn test

they are executed correctly and there is no exception. Am I missing something as far as a dependency goes? I have generated the eclipse project using

mvn eclipse:eclipse

and my pom is:

<?xml version="1.0" encoding="UTF-8"?>

http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0

<groupId>com.myproject</groupId>
<artifactId>myproject</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<name>myproject</name>

<dependencies>
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.1.2</version>
    </dependency>
    <dependency>
        <groupId>taglibs</groupId>
        <artifactId>standard</artifactId>
        <version>1.1.2</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.3.2.GA</version>
    </dependency>
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc14</artifactId>
        <version>10.1.0.4.0</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.0</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.6.0</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.14</version>
    </dependency>
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.8.0.GA</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>3.4.0.GA</version>
    </dependency>

    <!-- Test Dependencies -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.easymock</groupId>
        <artifactId>easymock</artifactId>
        <version>3.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <version>1.8.0.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>jetty-servlet-tester</artifactId>
        <version>6.1.24</version>
        <scope>test</scope>
    </dependency>


    <!-- Provided -->
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>servlet-api</artifactId>
        <version>6.0.26</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>jsp-api</artifactId>
        <version>6.0.26</version>
    </dependency>

</dependencies>

<build>
    <finalName>ww_main</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>maven-jetty-plugin</artifactId>
        </plugin>
    </plugins>
</build>
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

Update Ok, well not sure what exactly was going wrong here, but I seemed to have fixed it. I deleted all the files that HSQLDB created, as well as all of the created files in my Maven target folder, did a clean, recreated my eclipse .project using maven and refreshed the project in eclipse. I think I may have had something left over from a previous configuration that was throwing it off.

Thanks for everyone's help!

A: 

What about starting server through Runtime.getRuntime().exec("shell command here")? You have to do it only once for all tests, so it won't add too big lag.

Update
Ok, looks like you've solved it yourself :)

Update 2
To execute some code once before (or after) unit tests, you can

static class TestWrapper extends TestSetup {
    TestWrapper(TestSuite suite) {
        super(suite);
    }

    protected void setUp() throws Exception {
        // start db
    }

    protected void tearDown() throws Exception {
        // kill db
    }
}

Then, just wrap your test set in it: new TestWrapper(suite)

Nikita Rybak
this hasn't quite solved it I don't think. I'm working on moving it into a test suite where it gets executed only once, but there seems to be something wrong with it. I can't quite put my finger on it yet though.
Casey
Updated. I did this stuff a lot, so just copypaste from my project :)
Nikita Rybak
+2  A: 

Try appending this to the jdbc url:

;ifexists=true;shutdown=true;
Nathan Hughes
+2  A: 

I use the following configuration (directly inspired by the Hibernate tutorial) without any problem:

<hibernate-configuration>
  <session-factory>

    <!-- Database connection settings -->
    <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
    <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:foobar"/>
    <property name="hibernate.connection.username" value="sa"/>
    <property name="hibernate.connection.password" value=""/>

    <!-- JDBC connection pool (use the built-in) -->
    <property name="connection.pool_size">1</property>

    <!-- SQL dialect -->
    <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>

    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>

    <!-- Disable the second-level cache  -->
    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

    <!-- Echo all executed SQL to stdout -->
    <property name="show_sql">true</property>

    <!-- Drop and re-create the database schema on startup -->
    <property name="hibernate.hbm2ddl.auto" value="update"/>

    <mapping resource="..."/>

  </session-factory>
</hibernate-configuration>

When using an in-memory HSQLDB, there is no need to start anything explicitly. Just use the mem: protocol and the in-memory database will get started from JDBC.

See also

Pascal Thivent
This is exactly what I'm doing, but when I run the unit test I get a java.sql.SQLException: socket creation error. I also get a [main] WARN org.hibernate.cfg.SettingsFactory - Could not obtain connection to query metadata from hibernate.
Casey
I've noticed that it also is always creating files in my classpath that I would expect to be created if I was using a file based DB and not an in memory one.
Casey
I'm giving you the answer for confirming that my configuration was correct, leading me to look at other reasons this was failing. Thanks!
Casey
@Casey Glad it's solved and thanks. I was actually about to answer: double check your config, you must have a conflict somewhere :)
Pascal Thivent