Datastore refactor and added postgres tests (#259)

* fix apps & routes creation/update

* refactor datastore and added postgres tests

* added test-datastore and fixed circleci test
This commit is contained in:
Pedro Nasser
2016-11-14 15:03:10 -02:00
committed by GitHub
parent ff8c5538dd
commit 7aa1981fba
19 changed files with 776 additions and 110 deletions

View File

@@ -41,7 +41,7 @@ func handleAppCreate(c *gin.Context) {
return
}
_, err = Api.Datastore.StoreApp(wapp.App)
_, err = Api.Datastore.InsertApp(wapp.App)
if err != nil {
log.WithError(err).Errorln(models.ErrAppsCreate)
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsCreate))

View File

@@ -26,28 +26,29 @@ func setLogBuffer() *bytes.Buffer {
func TestAppCreate(t *testing.T) {
buf := setLogBuffer()
New(&datastore.Mock{}, &mqs.Mock{}, testRunner(t))
s := New(&datastore.Mock{}, &mqs.Mock{}, testRunner(t))
router := testRouter(s)
for i, test := range []struct {
mock *datastore.Mock
path string
body string
expectedCode int
expectedError error
}{
// errors
{"/v1/apps", ``, http.StatusBadRequest, models.ErrInvalidJSON},
{"/v1/apps", `{}`, http.StatusBadRequest, models.ErrAppsMissingNew},
{"/v1/apps", `{ "name": "Test" }`, http.StatusBadRequest, models.ErrAppsMissingNew},
{"/v1/apps", `{ "app": { "name": "" } }`, http.StatusInternalServerError, models.ErrAppsValidationMissingName},
{"/v1/apps", `{ "app": { "name": "1234567890123456789012345678901" } }`, http.StatusInternalServerError, models.ErrAppsValidationTooLongName},
{"/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
{"/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
{&datastore.Mock{}, "/v1/apps", ``, http.StatusBadRequest, models.ErrInvalidJSON},
{&datastore.Mock{}, "/v1/apps", `{}`, http.StatusBadRequest, models.ErrAppsMissingNew},
{&datastore.Mock{}, "/v1/apps", `{ "name": "Test" }`, http.StatusBadRequest, models.ErrAppsMissingNew},
{&datastore.Mock{}, "/v1/apps", `{ "app": { "name": "" } }`, http.StatusInternalServerError, models.ErrAppsValidationMissingName},
{&datastore.Mock{}, "/v1/apps", `{ "app": { "name": "1234567890123456789012345678901" } }`, http.StatusInternalServerError, models.ErrAppsValidationTooLongName},
{&datastore.Mock{}, "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
{&datastore.Mock{}, "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
// success
{"/v1/apps", `{ "app": { "name": "teste" } }`, http.StatusCreated, nil},
{&datastore.Mock{}, "/v1/apps", `{ "app": { "name": "teste" } }`, http.StatusCreated, nil},
} {
s := New(test.mock, &mqs.Mock{}, testRunner(t))
router := testRouter(s)
body := bytes.NewBuffer([]byte(test.body))
_, rec := routerRequest(t, router, "POST", test.path, body)
@@ -171,21 +172,27 @@ func TestAppGet(t *testing.T) {
func TestAppUpdate(t *testing.T) {
buf := setLogBuffer()
s := New(&datastore.Mock{}, &mqs.Mock{}, testRunner(t))
router := testRouter(s)
for i, test := range []struct {
mock *datastore.Mock
path string
body string
expectedCode int
expectedError error
}{
// errors
{"/v1/apps/myapp", ``, http.StatusBadRequest, models.ErrInvalidJSON},
{&datastore.Mock{}, "/v1/apps/myapp", ``, http.StatusBadRequest, models.ErrInvalidJSON},
// success
{"/v1/apps/myapp", `{ "app": { "config": { "test": "1" } } }`, http.StatusOK, nil},
{&datastore.Mock{
FakeApp: &models.App{
Name: "myapp",
},
}, "/v1/apps/myapp", `{ "app": { "config": { "test": "1" } } }`, http.StatusOK, nil},
} {
s := New(test.mock, &mqs.Mock{}, testRunner(t))
router := testRouter(s)
body := bytes.NewBuffer([]byte(test.body))
_, rec := routerRequest(t, router, "PUT", test.path, body)

View File

@@ -28,10 +28,10 @@ func handleAppUpdate(c *gin.Context) {
return
}
app, err := Api.Datastore.StoreApp(wapp.App)
app, err := Api.Datastore.UpdateApp(wapp.App)
if err != nil {
log.WithError(err).Debug(models.ErrAppsCreate)
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsCreate))
log.WithError(err).Debug(models.ErrAppsUpdate)
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsUpdate))
return
}

View File

@@ -53,6 +53,7 @@ func handleRouteCreate(c *gin.Context) {
}
if app == nil {
// Create a new application and add the route to that new application
newapp := &models.App{Name: wroute.Route.AppName}
if err := newapp.Validate(); err != nil {
log.Error(err)
@@ -60,7 +61,7 @@ func handleRouteCreate(c *gin.Context) {
return
}
app, err = Api.Datastore.StoreApp(newapp)
app, err = Api.Datastore.InsertApp(newapp)
if err != nil {
log.WithError(err).Error(models.ErrAppsCreate)
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsCreate))
@@ -68,7 +69,7 @@ func handleRouteCreate(c *gin.Context) {
}
}
_, err = Api.Datastore.StoreRoute(wroute.Route)
_, err = Api.Datastore.InsertRoute(wroute.Route)
if err != nil {
log.WithError(err).Error(models.ErrRoutesCreate)
c.JSON(http.StatusInternalServerError, simpleError(models.ErrRoutesCreate))

View File

@@ -13,27 +13,29 @@ import (
func TestRouteCreate(t *testing.T) {
buf := setLogBuffer()
s := New(&datastore.Mock{}, &mqs.Mock{}, testRunner(t))
router := testRouter(s)
for i, test := range []struct {
mock *datastore.Mock
path string
body string
expectedCode int
expectedError error
}{
// errors
{"/v1/apps/a/routes", ``, http.StatusBadRequest, models.ErrInvalidJSON},
{"/v1/apps/a/routes", `{ }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{"/v1/apps/a/routes", `{ "path": "/myroute" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{"/v1/apps/a/routes", `{ "route": { } }`, http.StatusInternalServerError, models.ErrRoutesValidationMissingImage},
{"/v1/apps/a/routes", `{ "route": { "image": "iron/hello" } }`, http.StatusInternalServerError, models.ErrRoutesValidationMissingPath},
{"/v1/apps/a/routes", `{ "route": { "image": "iron/hello", "path": "myroute" } }`, http.StatusInternalServerError, models.ErrRoutesValidationInvalidPath},
{"/v1/apps/$/routes", `{ "route": { "image": "iron/hello", "path": "/myroute" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
{&datastore.Mock{}, "/v1/apps/a/routes", ``, http.StatusBadRequest, models.ErrInvalidJSON},
{&datastore.Mock{}, "/v1/apps/a/routes", `{ }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{&datastore.Mock{}, "/v1/apps/a/routes", `{ "path": "/myroute" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
{&datastore.Mock{}, "/v1/apps/a/routes", `{ "route": { } }`, http.StatusInternalServerError, models.ErrRoutesValidationMissingImage},
{&datastore.Mock{}, "/v1/apps/a/routes", `{ "route": { "image": "iron/hello" } }`, http.StatusInternalServerError, models.ErrRoutesValidationMissingPath},
{&datastore.Mock{}, "/v1/apps/a/routes", `{ "route": { "image": "iron/hello", "path": "myroute" } }`, http.StatusInternalServerError, models.ErrRoutesValidationInvalidPath},
{&datastore.Mock{}, "/v1/apps/$/routes", `{ "route": { "image": "iron/hello", "path": "/myroute" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
// success
{"/v1/apps/a/routes", `{ "route": { "name": "myroute", "image": "iron/hello", "path": "/myroute" } }`, http.StatusCreated, nil},
{&datastore.Mock{}, "/v1/apps/a/routes", `{ "route": { "image": "iron/hello", "path": "/myroute" } }`, http.StatusCreated, nil},
} {
s := New(test.mock, &mqs.Mock{}, testRunner(t))
router := testRouter(s)
body := bytes.NewBuffer([]byte(test.body))
_, rec := routerRequest(t, router, "POST", test.path, body)

View File

@@ -37,10 +37,10 @@ func handleRouteUpdate(c *gin.Context) {
return
}
_, err = Api.Datastore.StoreRoute(wroute.Route)
_, err = Api.Datastore.UpdateRoute(wroute.Route)
if err != nil {
log.WithError(err).Debug(models.ErrAppsCreate)
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsCreate))
log.WithError(err).Debug(models.ErrRoutesUpdate)
c.JSON(http.StatusInternalServerError, simpleError(models.ErrRoutesUpdate))
return
}

View File

@@ -2,7 +2,6 @@ package server
import (
"bytes"
"fmt"
"net/http"
"strings"
"testing"
@@ -92,7 +91,6 @@ func TestRouteRunnerPost(t *testing.T) {
resp := getErrorResponse(t, rec)
respMsg := resp.Error.Message
expMsg := test.expectedError.Error()
fmt.Println(respMsg == expMsg)
if respMsg != expMsg && !strings.Contains(respMsg, expMsg) {
t.Log(buf.String())
t.Errorf("Test %d: Expected error message to have `%s`",
@@ -165,7 +163,6 @@ func TestMatchRoute(t *testing.T) {
for j, param := range test.expectedParams {
if params[j].Key != param.Key || params[j].Value != param.Value {
t.Log(buf.String())
fmt.Println(params[j])
t.Errorf("Test %d: expected param %d, key = %s, value = %s", i, j, param.Key, param.Value)
}
}

View File

@@ -3,6 +3,7 @@ package server
import (
"context"
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"path"
@@ -185,6 +186,8 @@ func (s *Server) bindHandlers() {
engine.NoRoute(handleSpecial)
}
var ErrInternalServerError = errors.New("Something unexpected happened on the server")
func simpleError(err error) *models.Error {
return &models.Error{&models.ErrorBody{Message: err.Error()}}
}

View File

@@ -72,6 +72,7 @@ func getErrorResponse(t *testing.T, rec *httptest.ResponseRecorder) models.Error
}
func prepareBolt(t *testing.T) (models.Datastore, func()) {
os.Remove(tmpBolt)
ds, err := datastore.New("bolt://" + tmpBolt)
if err != nil {
t.Fatal("Error when creating datastore: %s", err)