Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature - log migrations #45

Merged
merged 6 commits into from
Mar 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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