Skip to content

Commit

Permalink
Merge pull request Kong#45 from Mashape/feature/log-migrations
Browse files Browse the repository at this point in the history
Feature - log migrations
  • Loading branch information
thibaultcha committed Mar 2, 2015
2 parents d3e5835 + 3b769e4 commit 109fa47
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 117 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ TESTS_NGINX_CONF ?= $(TESTS_DIR)/nginx.conf
.PHONY: install dev clean migrate reset seed drop test coverage run-integration-tests test-web test-proxy test-all

install:
@echo "Please wait, this process could take some time.."
@if [ `uname` == "Darwin" ]; then \
luarocks make kong-*.rockspec; \
else \
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,16 @@ scripts/db.lua --help
# Migrate up
scripts/db.lua migrate [configuration_path] # for all commands, the default configuration_path is config.dev/kong.yml

# Migrate down (currently equivalent to reset)
# Revert latest migration
scripts/db.lua rollback

# Reset DB (danger!)
# Revert all migrations (danger! this will delete your data)
scripts/db.lua reset

# Seed DB
# Seed DB (danger! this will delete your data)
scripts/db.lua seed

# Drop DB (danger!)
# Drop DB (danger! this will delete your data)
scripts/db.lua drop
```

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
local Migration = {
name = "2015-01-12-175310_init_schema",

init = true,

up = function(options)
return [[
CREATE KEYSPACE IF NOT EXISTS "]]..options.keyspace..[["
WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1};
USE ]]..options.keyspace..[[;
CREATE TABLE IF NOT EXISTS schema_migrations(
id text PRIMARY KEY,
migrations list<text>
);
CREATE TABLE IF NOT EXISTS accounts(
id uuid,
provider_id text,
Expand Down
22 changes: 15 additions & 7 deletions scripts/db.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

local cli = require "cliargs"
local utils = require "kong.tools.utils"
local Faker = require "kong.tools.faker"
local Migrations = require "kong.tools.migrations"

cli:set_name("db.lua")
Expand All @@ -19,6 +20,8 @@ end
local logger = utils.logger:new(args.silent)
local configuration, dao = utils.load_configuration_and_dao(args.CONFIGURATION)

local migrations = Migrations(dao)

if args.COMMAND == "create" then

Migrations.create(configuration, args.name, function(interface, file_path, file_name)
Expand All @@ -33,34 +36,38 @@ elseif args.COMMAND == "migrate" then

logger:log("Migrating "..utils.yellow(dao.type))

dao:migrate(function(migration, err)
migrations:migrate(function(migration, err)
if err then
logger:error(err)
else
elseif migration then
logger:success("Migrated up to: "..utils.yellow(migration.name))
else
logger:success("Schema already up to date")
end
end)

elseif args.COMMAND == "rollback" then

logger:log("Rolling back "..utils.yellow(dao.type))

dao:rollback(function(migration, err)
migrations:rollback(function(migration, err)
if err then
logger:error(err)
else
elseif migration then
logger:success("Rollbacked to: "..utils.yellow(migration.name))
else
logger:success("No migration to rollback")
end
end)

elseif args.COMMAND == "reset" then

logger:log("Resetting "..utils.yellow(dao.type))

dao:reset(function(migration, err)
migrations:reset(function(migration, err)
if err then
logger:error(err)
else
elseif migration then
logger:success("Rollbacked: "..utils.yellow(migration.name))
end
end)
Expand All @@ -80,7 +87,8 @@ elseif args.COMMAND == "seed" then
logger:error(err)
end

dao:seed(args.random)
local faker = Faker(dao)
faker:seed(args.random)
logger:success("Populated")

elseif args.COMMAND == "drop" then
Expand Down
69 changes: 40 additions & 29 deletions spec/unit/dao/cassandra_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@ local constants = require "kong.constants"
local cjson = require "cjson"
local uuid = require "uuid"

-- Kong
-- Kong modules
local Faker = require "kong.tools.faker"
local Migrations = require "kong.tools.migrations"
local configuration = require "spec.dao_configuration"
local CassandraFactory = require "kong.dao.cassandra.factory"

-- Start instances
local dao_factory = CassandraFactory(configuration.cassandra)
local migrations = Migrations(dao_factory)
local faker = Faker(dao_factory)

-- An utility function to apply tests on each collection
local function describe_all_collections(tests_cb)
Expand All @@ -26,11 +32,15 @@ end
describe("Cassandra DAO #dao #cassandra", function()

setup(function()
local ok, err = dao_factory:migrate()
assert.falsy(err)
-- Migrate our schema
migrations:migrate(function(_, err)
assert.falsy(err)
end)

-- Prepare dao statements
dao_factory:prepare()
dao_factory:seed()
-- Seed DB with dummy entities
faker:seed()

-- Create a session to verify the dao's behaviour
session = cassandra.new()
Expand All @@ -47,8 +57,9 @@ describe("Cassandra DAO #dao #cassandra", function()
if session then
session:close()
end
local ok, err = dao_factory:reset()
assert.falsy(err)
migrations:reset(function(_, err)
assert.falsy(err)
end)
end)

describe("Factory", function()
Expand Down Expand Up @@ -90,7 +101,7 @@ describe("Cassandra DAO #dao #cassandra", function()
describe("APIs", function()

it("should insert in DB and add generated values", function()
local api_t = dao_factory.faker:fake_entity("api")
local api_t = faker:fake_entity("api")
local api, err = dao_factory.apis:insert(api_t)
assert.falsy(err)
assert.truthy(api.id)
Expand All @@ -108,7 +119,7 @@ describe("Cassandra DAO #dao #cassandra", function()
-- Invalid schema UNIQUE error (already existing API name)
local api_rows, err = session:execute("SELECT * FROM apis LIMIT 1;")
assert.falsy(err)
local api_t = dao_factory.faker:fake_entity("api")
local api_t = faker:fake_entity("api")
api_t.name = api_rows[1].name

local api, err = dao_factory.apis:insert(api_t)
Expand All @@ -122,7 +133,7 @@ describe("Cassandra DAO #dao #cassandra", function()
assert.falsy(err)
assert.truthy(#apis > 0)

local api_t = dao_factory.faker:fake_entity("api")
local api_t = faker:fake_entity("api")
api_t.name = apis[1].name
local api, err = dao_factory.apis:insert(api_t)
assert.falsy(api)
Expand All @@ -136,7 +147,7 @@ describe("Cassandra DAO #dao #cassandra", function()
describe("Accounts", function()

it("should insert an account in DB and add generated values", function()
local account_t = dao_factory.faker:fake_entity("account")
local account_t = faker:fake_entity("account")
local account, err = dao_factory.accounts:insert(account_t)
assert.falsy(err)
assert.truthy(account.id)
Expand All @@ -149,7 +160,7 @@ describe("Cassandra DAO #dao #cassandra", function()

it("should not insert in DB if account does not exist", function()
-- Without an account_id, it's a schema error
local app_t = dao_factory.faker:fake_entity("application")
local app_t = faker:fake_entity("application")
app_t.account_id = nil
local app, err = dao_factory.applications:insert(app_t)
assert.falsy(app)
Expand All @@ -158,7 +169,7 @@ describe("Cassandra DAO #dao #cassandra", function()
assert.are.same("account_id is required", err.message.account_id)

-- With an invalid account_id, it's a FOREIGN error
local app_t = dao_factory.faker:fake_entity("application")
local app_t = faker:fake_entity("application")
app_t.account_id = uuid()

local app, err = dao_factory.applications:insert(app_t)
Expand All @@ -173,7 +184,7 @@ describe("Cassandra DAO #dao #cassandra", function()
assert.falsy(err)
assert.truthy(#accounts > 0)

local app_t = dao_factory.faker:fake_entity("application")
local app_t = faker:fake_entity("application")
app_t.account_id = accounts[1].id

local app, err = dao_factory.applications:insert(app_t)
Expand All @@ -188,7 +199,7 @@ describe("Cassandra DAO #dao #cassandra", function()

it("should not insert in DB if invalid", function()
-- Without an api_id, it's a schema error
local plugin_t = dao_factory.faker:fake_entity("plugin")
local plugin_t = faker:fake_entity("plugin")
plugin_t.api_id = nil
local plugin, err = dao_factory.plugins:insert(plugin_t)
assert.falsy(plugin)
Expand All @@ -197,7 +208,7 @@ describe("Cassandra DAO #dao #cassandra", function()
assert.are.same("api_id is required", err.message.api_id)

-- With an invalid api_id, it's an FOREIGN error
local plugin_t = dao_factory.faker:fake_entity("plugin")
local plugin_t = faker:fake_entity("plugin")
plugin_t.api_id = uuid()

local plugin, err = dao_factory.plugins:insert(plugin_t)
Expand All @@ -207,7 +218,7 @@ describe("Cassandra DAO #dao #cassandra", function()
assert.are.same("api_id "..plugin_t.api_id.." does not exist", err.message.api_id)

-- With invalid api_id and application_id, it's an EXISTS error
local plugin_t = dao_factory.faker:fake_entity("plugin")
local plugin_t = faker:fake_entity("plugin")
plugin_t.api_id = uuid()
plugin_t.application_id = uuid()

Expand All @@ -221,15 +232,15 @@ describe("Cassandra DAO #dao #cassandra", function()

it("should insert a plugin in DB and add generated values", function()
-- Create an API and get an Application for insert
local api_t = dao_factory.faker:fake_entity("api")
local api_t = faker:fake_entity("api")
local api, err = dao_factory.apis:insert(api_t)
assert.falsy(err)

local apps, err = session:execute("SELECT * FROM applications")
assert.falsy(err)
assert.True(#apps > 0)

local plugin_t = dao_factory.faker:fake_entity("plugin")
local plugin_t = faker:fake_entity("plugin")
plugin_t.api_id = api.id
plugin_t.application_id = apps[1].id

Expand All @@ -241,15 +252,15 @@ describe("Cassandra DAO #dao #cassandra", function()

it("should not insert twice a plugin with same api_id, application_id and name", function()
-- Insert a new API for a fresh start
local api, err = dao_factory.apis:insert(dao_factory.faker:fake_entity("api"))
local api, err = dao_factory.apis:insert(faker:fake_entity("api"))
assert.falsy(err)
assert.truthy(api.id)

local apps, err = session:execute("SELECT * FROM applications")
assert.falsy(err)
assert.True(#apps > 0)

local plugin_t = dao_factory.faker:fake_entity("plugin")
local plugin_t = faker:fake_entity("plugin")
plugin_t.api_id = api.id
plugin_t.application_id = apps[#apps].id

Expand All @@ -267,7 +278,7 @@ describe("Cassandra DAO #dao #cassandra", function()
end)

it("should not insert a plugin if this plugin doesn't exist (not installed)", function()
local plugin_t = dao_factory.faker:fake_entity("plugin")
local plugin_t = faker:fake_entity("plugin")
plugin_t.name = "world domination plugin"

-- This should fail
Expand All @@ -280,7 +291,7 @@ describe("Cassandra DAO #dao #cassandra", function()
it("should validate a plugin value schema", function()
-- Success
-- Insert a new API for a fresh start
local api, err = dao_factory.apis:insert(dao_factory.faker:fake_entity("api"))
local api, err = dao_factory.apis:insert(faker:fake_entity("api"))
assert.falsy(err)
assert.truthy(api.id)

Expand Down Expand Up @@ -323,7 +334,7 @@ describe("Cassandra DAO #dao #cassandra", function()
describe_all_collections(function(type, collection)

it("should return nil if no entity was found to update in DB", function()
local t = dao_factory.faker:fake_entity(type)
local t = faker:fake_entity(type)
t.id = uuid()

-- Remove immutable fields
Expand Down Expand Up @@ -462,12 +473,12 @@ describe("Cassandra DAO #dao #cassandra", function()

setup(function()
dao_factory:drop()
dao_factory:seed()
faker:seed()
end)

teardown(function()
dao_factory:drop()
dao_factory:seed()
faker:seed()
end)

describe_all_collections(function(type, collection)
Expand Down Expand Up @@ -501,12 +512,12 @@ describe("Cassandra DAO #dao #cassandra", function()

setup(function()
dao_factory:drop()
dao_factory:seed(true, 100)
faker:seed(true, 100)
end)

teardown(function()
dao_factory:drop()
dao_factory:seed()
faker:seed()
end)

describe_all_collections(function(type, collection)
Expand Down Expand Up @@ -778,11 +789,11 @@ describe("Cassandra DAO #dao #cassandra", function()
-- uuid...

-- Create an API
local api_t = dao_factory.faker:fake_entity("api")
local api_t = faker:fake_entity("api")
local api, err = dao_factory.apis:insert(api_t)
assert.falsy(err)

local plugin_t = dao_factory.faker:fake_entity("plugin")
local plugin_t = faker:fake_entity("plugin")
plugin_t.api_id = api.id
plugin_t.application_id = nil

Expand Down
Loading

0 comments on commit 109fa47

Please sign in to comment.