Databases and other services

What This Guide Covers

This guide covers data stores and other services (e.g. RabbitMQ) offered in the Travis CI environment and what users and settings projects hosted on travis-ci.org can rely on. Most of the content is applicable to any technology but there are subtle aspects in the behavior of some database drivers that this guide will try to cover. We recommend you start with the Getting Started and Build Configuration guides before reading this one.

Services (data stores, messaging brokers, etc) in the Travis CI Environment

Travis CI Environment has multiple popular data stores preinstalled. Some of the services available are:

All of these data stores use the default settings, with one exception: When it makes sense, new users are added and the security settings are relaxed for ease of use. One example of this is PostgreSQL which normally has very strict default access settings.

Configure Your Projects to Use Services in Tests

Here is how to configure your project to use databases in its tests. This assumes you have already read the Build configuration documentation.

Enabling Services

Most services are not started on boot to make more RAM available to project test suites.

If your project needs, say, MongoDB running, you can add the following to your .travis.yml:

services: mongodb

or if you need several services, you can use the following:

services:
  - riak     # will start riak
  - rabbitmq # will start rabbitmq-server
  - memcached # will start memcached

This allows us to provide nice aliases for each service and normalize common differences between names, like RabbitMQ for example. Note that this feature only works for services we provision in our CI environment. If you download, say, Apache Jackrabbit and start it manually in a before_install step, you will still have to do it the same way.

MySQL

MySQL on Travis CI is started on boot, binds to 127.0.0.1 and requires authentication. You can connect using the username "travis" or "root" and a blank password. Note that the "travis" user does not have full MySQL privileges that the "root" user does.

You might have to create the myapp_test database first. Run this as part of your build script:

# .travis.yml
before_script:
  - mysql -e 'create database myapp_test;'

config/database.yml Example

config/database.yml example for Ruby projects using ActiveRecord:

test:
  adapter: mysql2
  database: myapp_test
  username: travis
  encoding: utf8

PostgreSQL

Using PostgreSQL is covered in a separate guide.

SQLite3

Probably the easiest and simplest solution for your relation database needs. If you don't specifically want to test how your code behaves with other databases, in memory SQLite might be the best option.

Ruby Projects

For Ruby projects, ensure that you have the sqlite3 ruby bindings in your bundle:

# Gemfile
# for CRuby, Rubinius, including Windows and RubyInstaller
gem "sqlite3", :platform => [:ruby, :mswin, :mingw]

# for JRuby
gem "jdbc-sqlite3", :platform => :jruby

config/database.yml example for projects that use ActiveRecord:

test:
  adapter: sqlite3
  database: ":memory:"
  timeout: 500

If you're not using a config/database.yml file to configure ActiveRecord, you need to connect to the database manually in the tests. For example, connecting with ActiveRecord could be done like this:

ActiveRecord::Base.establish_connection :adapter => 'sqlite3',
                                        :database => ':memory:'

MongoDB

MongoDB is not started on boot. To make Travis CI start the service for you, add

services:
  - mongodb

to your .travis.yml.

MongoDB binds to 127.0.0.1 and requires no authentication or database creation up front. If you add an admin user, authentication will be enabled, since mongod is started with the --auth argument.

Note: Admin users are users created on the admin database.

In cases you need to create users for your database, you can do it using a before_script in your .travis.yml file:

# .travis.yml
before_script:
  - mongo mydb_test --eval 'db.addUser("travis", "test");'

CouchDB

CouchDB is not started on boot. To make Travis CI start the service for you, add

services:
  - couchdb

to your .travis.yml.

CouchDB binds to 127.0.0.1, uses stock configuration and requires no authentication (it runs in admin party).

You have to create the database as part of your build process:

# .travis.yml
before_script:
  - curl -X PUT localhost:5984/myapp_test

RabbitMQ

RabbitMQ is not started on boot. To make Travis CI start the service for you, add

services:
  - rabbitmq

to your .travis.yml.

RabbitMQ uses stock configuration, so default vhost (/), username (guest) and password (guest) can be relied on. You can set up more vhosts and roles via a before_script if needed (for example, to test authentication).

Riak

Riak is not started on boot. To make Travis CI start the service for you, add

services:
  - riak

to your .travis.yml.

Riak uses stock configuration with one exception: it is configured to use LevelDB storage backend. Riak Search is enabled.

Memcached

Memcached is not started on boot. To make Travis CI start the service for you, add

services:
  - memcached

to your .travis.yml.

Memcached uses stock configuration and binds to localhost.

Redis

Redis is not started on boot. To make Travis CI start the service for you, add

services:
  - redis-server

to your .travis.yml.

Redis uses stock configuration and is available on localhost.

Cassandra

Cassandra is not started on boot. To make Travis CI start the service for you, add

services:
  - cassandra

to your .travis.yml.

Cassandra is provided via Datastax Community Edition and uses stock configuration (available on 127.0.0.1).

Neo4J

Neo4J Server (Community Edition) is not started on boot. To make Travis CI start the service for you, add

services:
  - neo4j

to your .travis.yml.

Neo4J Server uses default configuration (localhost, port 7474).

ElasticSearch

ElasticSearch is not started on boot. To make Travis CI start the service for you, add

services:
  - elasticsearch

to your .travis.yml.

ElasticSearch is provided via official Debian packages and uses stock configuration (available on 127.0.0.1).

Note

When ElasticSearch is started, you may see a mangled message such as this:

$ sudo service elasticsearch start
 * Starting ElasticSearch Server       ission denied on key 'vm.max_map_count'

This is due to a recent change in ElasticSearch, as reported here. The message is harmless, and the service is functional.

Kestrel

Kestrel is not started on boot. To make Travis CI start the service for you, add

services:
  - kestrel

to your .travis.yml.

Multiple database systems

If your project's tests need to run multiple times using different databases, this can be configured on Travis CI using a technique with env variables. The technique is just a convention and requires a before_script or before_install line to work.

Using ENV variables and before_script steps

Now you use the "DB" environment variable to specify the name of the database configuration you want to use. Locally, you would run this as:

$ DB=postgres [commands to run your tests]

On Travis CI you want to create a matrix of three builds each having the DB variable exported with a different value, and for that you can use the "env" option:

# .travis.yml
env:
  - DB=sqlite
  - DB=mysql
  - DB=postgres

Then you can use those values in a before_install (or before_script) step or more to set up each database. For example:

before_script:
  - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests;' -U postgres; fi"
  - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS doctrine_tests_tmp;' -U postgres; fi"
  - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests;' -U postgres; fi"
  - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests_tmp;' -U postgres; fi"
  - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi"

When doing this, please read and understand everything about the build matrix described in Build configuration.

Note: Travis CI does not have any special support for these variables, it just creates three builds with different exported values. It is up to your test suite or before_install/before_script steps to make use of them.

For a real example, see doctrine/doctrine2 .travis.yml.

A Ruby-specific Approach

Another approach that is Ruby-specific is put all database configurations in one YAML file, like ActiveRecord does:

# test/database.yml
sqlite:
  adapter: sqlite3
  database: ":memory:"
  timeout: 500
mysql:
  adapter: mysql2
  database: myapp_test
  username:
  encoding: utf8
postgres:
  adapter: postgresql
  database: myapp_test
  username: postgres

Then, in your test suite, read that data into a configurations hash:

configs = YAML.load_file('test/database.yml')
ActiveRecord::Base.configurations = configs

db_name = ENV['DB'] || 'sqlite'
ActiveRecord::Base.establish_connection(db_name)
ActiveRecord::Base.default_timezone = :utc

Conclusion

Travis CI Environment provides several popular open source data stores that hosted projects can use. In the majority of cases, said data stores use stock configuration. When it is not the case, the purpose of customizing the configuration is usually to minimize the amount of work developers have to do to use them. Often this means relaxing security settings, which is OK for continuous integration environments.