mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
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:
7
Makefile
7
Makefile
@@ -14,15 +14,18 @@ build-docker:
|
|||||||
docker build -t iron/functions:latest .
|
docker build -t iron/functions:latest .
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test -v $(shell glide nv | grep -v examples | grep -v tool | grep -v fnctl)
|
go test -v $(shell go list ./... | grep -v vendor | grep -v examples | grep -v tool | grep -v fnctl)
|
||||||
cd fnctl && $(MAKE) test
|
cd fnctl && $(MAKE) test
|
||||||
|
|
||||||
|
test-datastore:
|
||||||
|
cd api/datastore && go test -v
|
||||||
|
|
||||||
test-docker:
|
test-docker:
|
||||||
docker run -ti --privileged --rm -e LOG_LEVEL=debug \
|
docker run -ti --privileged --rm -e LOG_LEVEL=debug \
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||||
-v $(DIR):/go/src/github.com/iron-io/functions \
|
-v $(DIR):/go/src/github.com/iron-io/functions \
|
||||||
-w /go/src/github.com/iron-io/functions iron/go:dev go test \
|
-w /go/src/github.com/iron-io/functions iron/go:dev go test \
|
||||||
-v $(shell glide nv | grep -v examples | grep -v tool | grep -v fnctl)
|
-v $(shell go list ./... | grep -v vendor | grep -v examples | grep -v tool | grep -v fnctl | grep -v datastore)
|
||||||
|
|
||||||
run:
|
run:
|
||||||
./functions
|
./functions
|
||||||
|
|||||||
@@ -72,18 +72,31 @@ func New(url *url.URL) (models.Datastore, error) {
|
|||||||
return ds, nil
|
return ds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *BoltDatastore) StoreApp(app *models.App) (*models.App, error) {
|
func (ds *BoltDatastore) InsertApp(app *models.App) (*models.App, error) {
|
||||||
if app == nil {
|
if app == nil {
|
||||||
return nil, models.ErrDatastoreEmptyApp
|
return nil, models.ErrDatastoreEmptyApp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if app.Name == "" {
|
||||||
|
return nil, models.ErrDatastoreEmptyAppName
|
||||||
|
}
|
||||||
|
|
||||||
|
appname := []byte(app.Name)
|
||||||
|
|
||||||
err := ds.db.Update(func(tx *bolt.Tx) error {
|
err := ds.db.Update(func(tx *bolt.Tx) error {
|
||||||
bIm := tx.Bucket(ds.appsBucket)
|
bIm := tx.Bucket(ds.appsBucket)
|
||||||
|
|
||||||
|
v := bIm.Get(appname)
|
||||||
|
if v != nil {
|
||||||
|
return models.ErrAppsAlreadyExists
|
||||||
|
}
|
||||||
|
|
||||||
buf, err := json.Marshal(app)
|
buf, err := json.Marshal(app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = bIm.Put([]byte(app.Name), buf)
|
|
||||||
|
err = bIm.Put(appname, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -94,6 +107,62 @@ func (ds *BoltDatastore) StoreApp(app *models.App) (*models.App, error) {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return app, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *BoltDatastore) UpdateApp(newapp *models.App) (*models.App, error) {
|
||||||
|
if newapp == nil {
|
||||||
|
return nil, models.ErrDatastoreEmptyApp
|
||||||
|
}
|
||||||
|
|
||||||
|
if newapp.Name == "" {
|
||||||
|
return nil, models.ErrDatastoreEmptyAppName
|
||||||
|
}
|
||||||
|
|
||||||
|
var app *models.App
|
||||||
|
appname := []byte(newapp.Name)
|
||||||
|
|
||||||
|
err := ds.db.Update(func(tx *bolt.Tx) error {
|
||||||
|
bIm := tx.Bucket(ds.appsBucket)
|
||||||
|
|
||||||
|
v := bIm.Get(appname)
|
||||||
|
if v == nil {
|
||||||
|
return models.ErrAppsNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
err := json.Unmarshal(v, &app)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update app fields
|
||||||
|
if newapp.Config != nil {
|
||||||
|
if app.Config == nil {
|
||||||
|
app.Config = map[string]string{}
|
||||||
|
}
|
||||||
|
for k, v := range newapp.Config {
|
||||||
|
app.Config[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := json.Marshal(app)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = bIm.Put(appname, buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
bjParent := tx.Bucket(ds.routesBucket)
|
||||||
|
_, err = bjParent.CreateBucketIfNotExists([]byte(app.Name))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
return app, err
|
return app, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,23 +250,114 @@ func (ds *BoltDatastore) getRouteBucketForApp(tx *bolt.Tx, appName string) (*bol
|
|||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *BoltDatastore) StoreRoute(route *models.Route) (*models.Route, error) {
|
func (ds *BoltDatastore) InsertRoute(route *models.Route) (*models.Route, error) {
|
||||||
if route == nil {
|
if route == nil {
|
||||||
return nil, models.ErrDatastoreEmptyApp
|
return nil, models.ErrDatastoreEmptyApp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if route.AppName == "" {
|
||||||
|
return nil, models.ErrDatastoreEmptyAppName
|
||||||
|
}
|
||||||
|
|
||||||
|
if route.Path == "" {
|
||||||
|
return nil, models.ErrDatastoreEmptyRoutePath
|
||||||
|
}
|
||||||
|
|
||||||
|
routePath := []byte(route.Path)
|
||||||
|
|
||||||
err := ds.db.Update(func(tx *bolt.Tx) error {
|
err := ds.db.Update(func(tx *bolt.Tx) error {
|
||||||
b, err := ds.getRouteBucketForApp(tx, route.AppName)
|
b, err := ds.getRouteBucketForApp(tx, route.AppName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v := b.Get(routePath)
|
||||||
|
if v != nil {
|
||||||
|
return models.ErrRoutesAlreadyExists
|
||||||
|
}
|
||||||
|
|
||||||
buf, err := json.Marshal(route)
|
buf, err := json.Marshal(route)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = b.Put([]byte(route.Path), buf)
|
err = b.Put(routePath, buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return route, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *BoltDatastore) UpdateRoute(newroute *models.Route) (*models.Route, error) {
|
||||||
|
if newroute == nil {
|
||||||
|
return nil, models.ErrDatastoreEmptyRoute
|
||||||
|
}
|
||||||
|
|
||||||
|
if newroute.AppName == "" {
|
||||||
|
return nil, models.ErrDatastoreEmptyAppName
|
||||||
|
}
|
||||||
|
|
||||||
|
if newroute.Path == "" {
|
||||||
|
return nil, models.ErrDatastoreEmptyRoutePath
|
||||||
|
}
|
||||||
|
|
||||||
|
routePath := []byte(newroute.Path)
|
||||||
|
|
||||||
|
var route *models.Route
|
||||||
|
|
||||||
|
err := ds.db.Update(func(tx *bolt.Tx) error {
|
||||||
|
b, err := ds.getRouteBucketForApp(tx, newroute.AppName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
v := b.Get(routePath)
|
||||||
|
if v == nil {
|
||||||
|
return models.ErrRoutesNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(v, &route)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Update route fields
|
||||||
|
if newroute.Image != "" {
|
||||||
|
route.Image = newroute.Image
|
||||||
|
}
|
||||||
|
if route.Memory != 0 {
|
||||||
|
route.Memory = newroute.Memory
|
||||||
|
}
|
||||||
|
if route.Type != "" {
|
||||||
|
route.Type = newroute.Type
|
||||||
|
}
|
||||||
|
if newroute.Headers != nil {
|
||||||
|
if route.Config == nil {
|
||||||
|
route.Config = map[string]string{}
|
||||||
|
}
|
||||||
|
for k, v := range newroute.Headers {
|
||||||
|
route.Headers[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if newroute.Config != nil {
|
||||||
|
if route.Config == nil {
|
||||||
|
route.Config = map[string]string{}
|
||||||
|
}
|
||||||
|
for k, v := range newroute.Config {
|
||||||
|
route.Config[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf, err := json.Marshal(route)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = b.Put(routePath, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,15 +21,16 @@ func setLogBuffer() *bytes.Buffer {
|
|||||||
return &buf
|
return &buf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tmpBolt = "/tmp/func_test_bolt.db"
|
||||||
|
|
||||||
func TestBolt(t *testing.T) {
|
func TestBolt(t *testing.T) {
|
||||||
buf := setLogBuffer()
|
buf := setLogBuffer()
|
||||||
|
|
||||||
const tmpBolt = "/tmp/func_test_bolt.db"
|
os.Remove(tmpBolt)
|
||||||
ds, err := New("bolt://" + tmpBolt)
|
ds, err := New("bolt://" + tmpBolt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Error when creating datastore: %s", err)
|
t.Fatalf("Error when creating datastore: %v", err)
|
||||||
}
|
}
|
||||||
defer os.Remove(tmpBolt)
|
|
||||||
|
|
||||||
testApp := &models.App{
|
testApp := &models.App{
|
||||||
Name: "Test",
|
Name: "Test",
|
||||||
@@ -41,24 +42,47 @@ func TestBolt(t *testing.T) {
|
|||||||
Image: "iron/hello",
|
Image: "iron/hello",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Testing store app
|
// Testing insert app
|
||||||
_, err = ds.StoreApp(nil)
|
_, err = ds.InsertApp(nil)
|
||||||
if err == nil {
|
if err != models.ErrDatastoreEmptyApp {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test StoreApp: expected error when using nil app", err)
|
t.Fatalf("Test InsertApp(nil): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyApp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = ds.StoreApp(testApp)
|
_, err = ds.InsertApp(&models.App{})
|
||||||
|
if err != models.ErrDatastoreEmptyAppName {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test InsertApp(nil): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.InsertApp(testApp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test StoreApp: error when Bolt was storing new app: %s", err)
|
t.Fatalf("Test InsertApp: error when Bolt was storing new app: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.InsertApp(testApp)
|
||||||
|
if err != models.ErrAppsAlreadyExists {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test InsertApp duplicated: expected error `%v`, but it was `%v`", models.ErrAppsAlreadyExists, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.UpdateApp(&models.App{
|
||||||
|
Name: testApp.Name,
|
||||||
|
Config: map[string]string{
|
||||||
|
"TEST": "1",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test UpdateApp: error when Bolt was updating app: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Testing get app
|
// Testing get app
|
||||||
_, err = ds.GetApp("")
|
_, err = ds.GetApp("")
|
||||||
if err == nil {
|
if err != models.ErrDatastoreEmptyAppName {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test GetApp: expected error when using empty app name", err)
|
t.Fatalf("Test GetApp: expected error to be %v, but it was %s", models.ErrDatastoreEmptyAppName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
app, err := ds.GetApp(testApp.Name)
|
app, err := ds.GetApp(testApp.Name)
|
||||||
@@ -75,7 +99,7 @@ func TestBolt(t *testing.T) {
|
|||||||
apps, err := ds.GetApps(&models.AppFilter{})
|
apps, err := ds.GetApps(&models.AppFilter{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test GetApps: error: %s", err)
|
t.Fatalf("Test GetApps: unexpected error %v", err)
|
||||||
}
|
}
|
||||||
if len(apps) == 0 {
|
if len(apps) == 0 {
|
||||||
t.Fatal("Test GetApps: expected result count to be greater than 0")
|
t.Fatal("Test GetApps: expected result count to be greater than 0")
|
||||||
@@ -87,9 +111,9 @@ func TestBolt(t *testing.T) {
|
|||||||
|
|
||||||
// Testing app delete
|
// Testing app delete
|
||||||
err = ds.RemoveApp("")
|
err = ds.RemoveApp("")
|
||||||
if err == nil {
|
if err != models.ErrDatastoreEmptyAppName {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test RemoveApp: expected error when using empty app name", err)
|
t.Fatalf("Test RemoveApp: expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ds.RemoveApp(testApp.Name)
|
err = ds.RemoveApp(testApp.Name)
|
||||||
@@ -107,39 +131,63 @@ func TestBolt(t *testing.T) {
|
|||||||
t.Fatalf("Test RemoveApp: failed to remove the app")
|
t.Fatalf("Test RemoveApp: failed to remove the app")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store app again to test routes
|
// Test update inexistent app
|
||||||
ds.StoreApp(testApp)
|
_, err = ds.UpdateApp(&models.App{
|
||||||
|
Name: testApp.Name,
|
||||||
// Testing store route
|
Config: map[string]string{
|
||||||
_, err = ds.StoreRoute(nil)
|
"TEST": "1",
|
||||||
if err == nil {
|
},
|
||||||
|
})
|
||||||
|
if err != models.ErrAppsNotFound {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test StoreRoute: expected error when using nil route", err)
|
t.Fatalf("Test UpdateApp inexistent: expected error to be %v, but it was %v", models.ErrAppsNotFound, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = ds.StoreRoute(testRoute)
|
// Insert app again to test routes
|
||||||
|
ds.InsertApp(testApp)
|
||||||
|
|
||||||
|
// Testing insert route
|
||||||
|
_, err = ds.InsertRoute(nil)
|
||||||
|
if err == models.ErrDatastoreEmptyRoute {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test InsertRoute(nil): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyRoute, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.InsertRoute(testRoute)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test StoreReoute: error when Bolt was storing new route: %s", err)
|
t.Fatalf("Test InsertRoute: error when Bolt was storing new route: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.InsertRoute(testRoute)
|
||||||
|
if err != models.ErrRoutesAlreadyExists {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test InsertRoute duplicated: expected error to be `%v`, but it was `%v`", models.ErrRoutesAlreadyExists, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.UpdateRoute(testRoute)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test UpdateRoute: unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Testing get
|
// Testing get
|
||||||
_, err = ds.GetRoute("a", "")
|
_, err = ds.GetRoute("a", "")
|
||||||
if err == nil {
|
if err != models.ErrDatastoreEmptyRoutePath {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test GetRoute: expected error when using empty route name", err)
|
t.Fatalf("Test GetRoute(empty route path): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyRoutePath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = ds.GetRoute("", "a")
|
_, err = ds.GetRoute("", "a")
|
||||||
if err == nil {
|
if err != models.ErrDatastoreEmptyAppName {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test GetRoute: expected error when using empty app name", err)
|
t.Fatalf("Test GetRoute(empty app name): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
route, err := ds.GetRoute(testApp.Name, testRoute.Path)
|
route, err := ds.GetRoute(testApp.Name, testRoute.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test GetRoute: error: %s", err)
|
t.Fatalf("Test GetRoute: unexpected error %v", err)
|
||||||
}
|
}
|
||||||
if route.Path != testRoute.Path {
|
if route.Path != testRoute.Path {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
@@ -150,7 +198,7 @@ func TestBolt(t *testing.T) {
|
|||||||
routes, err := ds.GetRoutesByApp(testApp.Name, &models.RouteFilter{})
|
routes, err := ds.GetRoutesByApp(testApp.Name, &models.RouteFilter{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test GetRoutes: error: %s", err)
|
t.Fatalf("Test GetRoutes: unexpected error %v", err)
|
||||||
}
|
}
|
||||||
if len(routes) == 0 {
|
if len(routes) == 0 {
|
||||||
t.Fatal("Test GetRoutes: expected result count to be greater than 0")
|
t.Fatal("Test GetRoutes: expected result count to be greater than 0")
|
||||||
@@ -176,21 +224,31 @@ func TestBolt(t *testing.T) {
|
|||||||
|
|
||||||
// Testing app delete
|
// Testing app delete
|
||||||
err = ds.RemoveRoute("", "")
|
err = ds.RemoveRoute("", "")
|
||||||
if err == nil {
|
if err != models.ErrDatastoreEmptyAppName {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test RemoveRoute: expected error when using empty app name", err)
|
t.Fatalf("Test RemoveRoute(empty app name): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ds.RemoveRoute("a", "")
|
err = ds.RemoveRoute("a", "")
|
||||||
if err == nil {
|
if err != models.ErrDatastoreEmptyRoutePath {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test RemoveRoute: expected error when using empty route name", err)
|
t.Fatalf("Test RemoveRoute(empty route path): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyRoutePath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ds.RemoveRoute(testRoute.AppName, testRoute.Path)
|
err = ds.RemoveRoute(testRoute.AppName, testRoute.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Fatalf("Test RemoveApp: error: %s", err)
|
t.Fatalf("Test RemoveApp: unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.UpdateRoute(&models.Route{
|
||||||
|
AppName: testRoute.AppName,
|
||||||
|
Path: testRoute.Path,
|
||||||
|
Image: "test",
|
||||||
|
})
|
||||||
|
if err != models.ErrRoutesNotFound {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test UpdateRoute inexistent: expected error to be `%v`, but it was `%v`", models.ErrRoutesNotFound, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
route, err = ds.GetRoute(testRoute.AppName, testRoute.Path)
|
route, err = ds.GetRoute(testRoute.AppName, testRoute.Path)
|
||||||
|
|||||||
@@ -27,7 +27,12 @@ func (m *Mock) GetApps(appFilter *models.AppFilter) ([]*models.App, error) {
|
|||||||
return m.FakeApps, nil
|
return m.FakeApps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mock) StoreApp(app *models.App) (*models.App, error) {
|
func (m *Mock) InsertApp(app *models.App) (*models.App, error) {
|
||||||
|
// TODO: improve this mock method
|
||||||
|
return m.FakeApp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Mock) UpdateApp(app *models.App) (*models.App, error) {
|
||||||
// TODO: improve this mock method
|
// TODO: improve this mock method
|
||||||
return m.FakeApp, nil
|
return m.FakeApp, nil
|
||||||
}
|
}
|
||||||
@@ -69,7 +74,12 @@ func (m *Mock) GetRoutesByApp(appName string, routeFilter *models.RouteFilter) (
|
|||||||
return routes, nil
|
return routes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Mock) StoreRoute(route *models.Route) (*models.Route, error) {
|
func (m *Mock) InsertRoute(route *models.Route) (*models.Route, error) {
|
||||||
|
// TODO: improve this mock method
|
||||||
|
return m.FakeRoute, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Mock) UpdateRoute(route *models.Route) (*models.Route, error) {
|
||||||
// TODO: improve this mock method
|
// TODO: improve this mock method
|
||||||
return m.FakeRoute, nil
|
return m.FakeRoute, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/iron-io/functions/api/models"
|
"github.com/iron-io/functions/api/models"
|
||||||
|
"github.com/lib/pq"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -75,17 +76,56 @@ func New(url *url.URL) (models.Datastore, error) {
|
|||||||
return pg, nil
|
return pg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *PostgresDatastore) StoreApp(app *models.App) (*models.App, error) {
|
func (ds *PostgresDatastore) InsertApp(app *models.App) (*models.App, error) {
|
||||||
|
var cbyte []byte
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if app == nil {
|
||||||
|
return nil, models.ErrDatastoreEmptyApp
|
||||||
|
}
|
||||||
|
|
||||||
|
if app.Name == "" {
|
||||||
|
return nil, models.ErrDatastoreEmptyAppName
|
||||||
|
}
|
||||||
|
|
||||||
|
if app.Config != nil {
|
||||||
|
cbyte, err = json.Marshal(app.Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.db.Exec(`INSERT INTO apps (name, config) VALUES ($1, $2);`,
|
||||||
|
app.Name,
|
||||||
|
string(cbyte),
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
pqErr := err.(*pq.Error)
|
||||||
|
if pqErr.Code == "23505" {
|
||||||
|
return nil, models.ErrAppsAlreadyExists
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return app, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *PostgresDatastore) UpdateApp(app *models.App) (*models.App, error) {
|
||||||
|
if app == nil {
|
||||||
|
return nil, models.ErrAppsNotFound
|
||||||
|
}
|
||||||
|
|
||||||
cbyte, err := json.Marshal(app.Config)
|
cbyte, err := json.Marshal(app.Config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = ds.db.Exec(`
|
res, err := ds.db.Exec(`
|
||||||
INSERT INTO apps (name, config)
|
UPDATE apps SET
|
||||||
VALUES ($1, $2)
|
config = $2
|
||||||
ON CONFLICT (name) DO UPDATE SET
|
WHERE name = $1
|
||||||
config = $2;
|
RETURNING *;
|
||||||
`,
|
`,
|
||||||
app.Name,
|
app.Name,
|
||||||
string(cbyte),
|
string(cbyte),
|
||||||
@@ -95,10 +135,23 @@ func (ds *PostgresDatastore) StoreApp(app *models.App) (*models.App, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n, err := res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
return nil, models.ErrAppsNotFound
|
||||||
|
}
|
||||||
|
|
||||||
return app, nil
|
return app, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *PostgresDatastore) RemoveApp(appName string) error {
|
func (ds *PostgresDatastore) RemoveApp(appName string) error {
|
||||||
|
if appName == "" {
|
||||||
|
return models.ErrDatastoreEmptyAppName
|
||||||
|
}
|
||||||
|
|
||||||
_, err := ds.db.Exec(`
|
_, err := ds.db.Exec(`
|
||||||
DELETE FROM apps
|
DELETE FROM apps
|
||||||
WHERE name = $1
|
WHERE name = $1
|
||||||
@@ -112,6 +165,10 @@ func (ds *PostgresDatastore) RemoveApp(appName string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ds *PostgresDatastore) GetApp(name string) (*models.App, error) {
|
func (ds *PostgresDatastore) GetApp(name string) (*models.App, error) {
|
||||||
|
if name == "" {
|
||||||
|
return nil, models.ErrDatastoreEmptyAppName
|
||||||
|
}
|
||||||
|
|
||||||
row := ds.db.QueryRow("SELECT name, config FROM apps WHERE name=$1", name)
|
row := ds.db.QueryRow("SELECT name, config FROM apps WHERE name=$1", name)
|
||||||
|
|
||||||
var resName string
|
var resName string
|
||||||
@@ -125,6 +182,9 @@ func (ds *PostgresDatastore) GetApp(name string) (*models.App, error) {
|
|||||||
json.Unmarshal([]byte(config), &res.Config)
|
json.Unmarshal([]byte(config), &res.Config)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil, models.ErrAppsNotFound
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,10 +192,19 @@ func (ds *PostgresDatastore) GetApp(name string) (*models.App, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func scanApp(scanner rowScanner, app *models.App) error {
|
func scanApp(scanner rowScanner, app *models.App) error {
|
||||||
|
var configStr string
|
||||||
|
|
||||||
err := scanner.Scan(
|
err := scanner.Scan(
|
||||||
&app.Name,
|
&app.Name,
|
||||||
|
&configStr,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if configStr == "" {
|
||||||
|
return models.ErrAppsNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
json.Unmarshal([]byte(configStr), &app.Config)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,18 +225,25 @@ func (ds *PostgresDatastore) GetApps(filter *models.AppFilter) ([]*models.App, e
|
|||||||
err := scanApp(rows, &app)
|
err := scanApp(rows, &app)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
if err == sql.ErrNoRows {
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
return res, err
|
||||||
}
|
}
|
||||||
res = append(res, &app)
|
res = append(res, &app)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := rows.Err(); err != nil {
|
if err := rows.Err(); err != nil {
|
||||||
return nil, err
|
return res, err
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *PostgresDatastore) StoreRoute(route *models.Route) (*models.Route, error) {
|
func (ds *PostgresDatastore) InsertRoute(route *models.Route) (*models.Route, error) {
|
||||||
|
if route == nil {
|
||||||
|
return nil, models.ErrDatastoreEmptyRoute
|
||||||
|
}
|
||||||
|
|
||||||
hbyte, err := json.Marshal(route.Headers)
|
hbyte, err := json.Marshal(route.Headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -187,14 +263,47 @@ func (ds *PostgresDatastore) StoreRoute(route *models.Route) (*models.Route, err
|
|||||||
headers,
|
headers,
|
||||||
config
|
config
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6)
|
VALUES ($1, $2, $3, $4, $5, $6);`,
|
||||||
ON CONFLICT (app_name, path) DO UPDATE SET
|
route.AppName,
|
||||||
path = $2,
|
route.Path,
|
||||||
|
route.Image,
|
||||||
|
route.Memory,
|
||||||
|
string(hbyte),
|
||||||
|
string(cbyte),
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
pqErr := err.(*pq.Error)
|
||||||
|
if pqErr.Code == "23505" {
|
||||||
|
return nil, models.ErrRoutesAlreadyExists
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return route, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *PostgresDatastore) UpdateRoute(route *models.Route) (*models.Route, error) {
|
||||||
|
if route == nil {
|
||||||
|
return nil, models.ErrDatastoreEmptyRoute
|
||||||
|
}
|
||||||
|
|
||||||
|
hbyte, err := json.Marshal(route.Headers)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cbyte, err := json.Marshal(route.Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := ds.db.Exec(`
|
||||||
|
UPDATE routes SET
|
||||||
image = $3,
|
image = $3,
|
||||||
memory = $4,
|
memory = $4,
|
||||||
headers = $5,
|
headers = $5,
|
||||||
config = $6;
|
config = $6
|
||||||
`,
|
WHERE app_name = $1 AND path = $2;`,
|
||||||
route.AppName,
|
route.AppName,
|
||||||
route.Path,
|
route.Path,
|
||||||
route.Image,
|
route.Image,
|
||||||
@@ -206,11 +315,29 @@ func (ds *PostgresDatastore) StoreRoute(route *models.Route) (*models.Route, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n, err := res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
return nil, models.ErrRoutesNotFound
|
||||||
|
}
|
||||||
|
|
||||||
return route, nil
|
return route, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *PostgresDatastore) RemoveRoute(appName, routePath string) error {
|
func (ds *PostgresDatastore) RemoveRoute(appName, routePath string) error {
|
||||||
_, err := ds.db.Exec(`
|
if appName == "" {
|
||||||
|
return models.ErrDatastoreEmptyAppName
|
||||||
|
}
|
||||||
|
|
||||||
|
if routePath == "" {
|
||||||
|
return models.ErrDatastoreEmptyRoutePath
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := ds.db.Exec(`
|
||||||
DELETE FROM routes
|
DELETE FROM routes
|
||||||
WHERE path = $1 AND app_name = $2
|
WHERE path = $1 AND app_name = $2
|
||||||
`, routePath, appName)
|
`, routePath, appName)
|
||||||
@@ -218,6 +345,16 @@ func (ds *PostgresDatastore) RemoveRoute(appName, routePath string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n, err := res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
return models.ErrRoutesRemoving
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,10 +381,18 @@ func scanRoute(scanner rowScanner, route *models.Route) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRoute(qr rowQuerier, routePath string) (*models.Route, error) {
|
func (ds *PostgresDatastore) GetRoute(appName, routePath string) (*models.Route, error) {
|
||||||
|
if appName == "" {
|
||||||
|
return nil, models.ErrDatastoreEmptyAppName
|
||||||
|
}
|
||||||
|
|
||||||
|
if routePath == "" {
|
||||||
|
return nil, models.ErrDatastoreEmptyRoutePath
|
||||||
|
}
|
||||||
|
|
||||||
var route models.Route
|
var route models.Route
|
||||||
|
|
||||||
row := qr.QueryRow(fmt.Sprintf("%s WHERE path=$1", routeSelector), routePath)
|
row := ds.db.QueryRow(fmt.Sprintf("%s WHERE app_name=$1 AND path=$2", routeSelector), appName, routePath)
|
||||||
err := scanRoute(row, &route)
|
err := scanRoute(row, &route)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
@@ -258,10 +403,6 @@ func getRoute(qr rowQuerier, routePath string) (*models.Route, error) {
|
|||||||
return &route, nil
|
return &route, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *PostgresDatastore) GetRoute(appName, routePath string) (*models.Route, error) {
|
|
||||||
return getRoute(ds.db, routePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ds *PostgresDatastore) GetRoutes(filter *models.RouteFilter) ([]*models.Route, error) {
|
func (ds *PostgresDatastore) GetRoutes(filter *models.RouteFilter) ([]*models.Route, error) {
|
||||||
res := []*models.Route{}
|
res := []*models.Route{}
|
||||||
filterQuery := buildFilterQuery(filter)
|
filterQuery := buildFilterQuery(filter)
|
||||||
|
|||||||
277
api/datastore/postgres_test.go
Normal file
277
api/datastore/postgres_test.go
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
package datastore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/iron-io/functions/api/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
const tmpPostgres = "postgres://postgres@127.0.0.1:15432/funcs?sslmode=disable"
|
||||||
|
|
||||||
|
func preparePostgresTest() func() {
|
||||||
|
fmt.Println("initializing postgres for test")
|
||||||
|
exec.Command("docker", "rm", "-f", "iron-postgres-test").Run()
|
||||||
|
exec.Command("docker", "run", "--name", "iron-postgres-test", "-p", "15432:5432", "-d", "postgres").Run()
|
||||||
|
for {
|
||||||
|
db, err := sql.Open("postgres", "postgres://postgres@127.0.0.1:15432?sslmode=disable")
|
||||||
|
if err != nil {
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Exec(`CREATE DATABASE funcs;`)
|
||||||
|
_, err = db.Exec(`GRANT ALL PRIVILEGES ON DATABASE funcs TO postgres;`)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
fmt.Println("postgres for test ready")
|
||||||
|
return func() {
|
||||||
|
exec.Command("docker", "rm", "-f", "iron-postgres-test").Run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPostgres(t *testing.T) {
|
||||||
|
close := preparePostgresTest()
|
||||||
|
defer close()
|
||||||
|
buf := setLogBuffer()
|
||||||
|
|
||||||
|
ds, err := New(tmpPostgres)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error when creating datastore: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testApp := &models.App{
|
||||||
|
Name: "Test",
|
||||||
|
}
|
||||||
|
|
||||||
|
testRoute := &models.Route{
|
||||||
|
AppName: testApp.Name,
|
||||||
|
Path: "/test",
|
||||||
|
Image: "iron/hello",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing insert app
|
||||||
|
_, err = ds.InsertApp(nil)
|
||||||
|
if err != models.ErrDatastoreEmptyApp {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test InsertApp(nil): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyApp, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.InsertApp(&models.App{})
|
||||||
|
if err != models.ErrDatastoreEmptyAppName {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test InsertApp(nil): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.InsertApp(testApp)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test InsertApp: error when storing new app: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.InsertApp(testApp)
|
||||||
|
if err != models.ErrAppsAlreadyExists {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test InsertApp duplicated: expected error `%v`, but it was `%v`", models.ErrAppsAlreadyExists, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.UpdateApp(&models.App{
|
||||||
|
Name: testApp.Name,
|
||||||
|
Config: map[string]string{
|
||||||
|
"TEST": "1",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test UpdateApp: error when updating app: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing get app
|
||||||
|
_, err = ds.GetApp("")
|
||||||
|
if err != models.ErrDatastoreEmptyAppName {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetApp: expected error to be %v, but it was %s", models.ErrDatastoreEmptyAppName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
app, err := ds.GetApp(testApp.Name)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetApp: error: %s", err)
|
||||||
|
}
|
||||||
|
if app.Name != testApp.Name {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetApp: expected `app.Name` to be `%s` but it was `%s`", app.Name, testApp.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing list apps
|
||||||
|
apps, err := ds.GetApps(&models.AppFilter{})
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetApps: unexpected error %v", err)
|
||||||
|
}
|
||||||
|
if len(apps) == 0 {
|
||||||
|
t.Fatal("Test GetApps: expected result count to be greater than 0")
|
||||||
|
}
|
||||||
|
if apps[0].Name != testApp.Name {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetApps: expected `app.Name` to be `%s` but it was `%s`", app.Name, testApp.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing app delete
|
||||||
|
err = ds.RemoveApp("")
|
||||||
|
if err != models.ErrDatastoreEmptyAppName {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test RemoveApp: expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ds.RemoveApp(testApp.Name)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test RemoveApp: error: %s", err)
|
||||||
|
}
|
||||||
|
app, err = ds.GetApp(testApp.Name)
|
||||||
|
if err != models.ErrAppsNotFound {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetApp(removed): expected error `%v`, but it was `%v`", models.ErrAppsNotFound, err)
|
||||||
|
}
|
||||||
|
if app != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test RemoveApp: failed to remove the app")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test update inexistent app
|
||||||
|
_, err = ds.UpdateApp(&models.App{
|
||||||
|
Name: testApp.Name,
|
||||||
|
Config: map[string]string{
|
||||||
|
"TEST": "1",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != models.ErrAppsNotFound {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test UpdateApp(inexistent): expected error `%v`, but it was `%v`", models.ErrAppsNotFound, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert app again to test routes
|
||||||
|
ds.InsertApp(testApp)
|
||||||
|
|
||||||
|
// Testing insert route
|
||||||
|
_, err = ds.InsertRoute(nil)
|
||||||
|
if err != models.ErrDatastoreEmptyRoute {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test InsertRoute(nil): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyRoute, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.InsertRoute(testRoute)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test InsertRoute: error when storing new route: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.InsertRoute(testRoute)
|
||||||
|
if err != models.ErrRoutesAlreadyExists {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test InsertRoute duplicated: expected error to be `%v`, but it was `%v`", models.ErrRoutesAlreadyExists, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.UpdateRoute(testRoute)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test UpdateRoute: unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing get
|
||||||
|
_, err = ds.GetRoute("a", "")
|
||||||
|
if err != models.ErrDatastoreEmptyRoutePath {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetRoute(empty route path): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyRoutePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.GetRoute("", "a")
|
||||||
|
if err != models.ErrDatastoreEmptyAppName {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetRoute(empty app name): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
route, err := ds.GetRoute(testApp.Name, testRoute.Path)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetRoute: unexpected error %v", err)
|
||||||
|
}
|
||||||
|
if route.Path != testRoute.Path {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetRoute: expected `route.Path` to be `%s` but it was `%s`", route.Path, testRoute.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing list routes
|
||||||
|
routes, err := ds.GetRoutesByApp(testApp.Name, &models.RouteFilter{})
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetRoutes: unexpected error %v", err)
|
||||||
|
}
|
||||||
|
if len(routes) == 0 {
|
||||||
|
t.Fatal("Test GetRoutes: expected result count to be greater than 0")
|
||||||
|
}
|
||||||
|
if routes[0].Path != testRoute.Path {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetRoutes: expected `app.Name` to be `%s` but it was `%s`", testRoute.Path, routes[0].Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing list routes
|
||||||
|
routes, err = ds.GetRoutes(&models.RouteFilter{Image: testRoute.Image})
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetRoutes: error: %s", err)
|
||||||
|
}
|
||||||
|
if len(routes) == 0 {
|
||||||
|
t.Fatal("Test GetRoutes: expected result count to be greater than 0")
|
||||||
|
}
|
||||||
|
if routes[0].Path != testRoute.Path {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetRoutes: expected `app.Name` to be `%s` but it was `%s`", testRoute.Path, routes[0].Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing app delete
|
||||||
|
err = ds.RemoveRoute("", "")
|
||||||
|
if err != models.ErrDatastoreEmptyAppName {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test RemoveRoute(empty app name): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ds.RemoveRoute("a", "")
|
||||||
|
if err != models.ErrDatastoreEmptyRoutePath {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test RemoveRoute(empty route path): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyRoutePath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ds.RemoveRoute(testRoute.AppName, testRoute.Path)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test RemoveApp: unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ds.UpdateRoute(&models.Route{
|
||||||
|
AppName: testRoute.AppName,
|
||||||
|
Path: testRoute.Path,
|
||||||
|
Image: "test",
|
||||||
|
})
|
||||||
|
if err != models.ErrRoutesNotFound {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test UpdateRoute inexistent: expected error to be `%v`, but it was `%v`", models.ErrRoutesNotFound, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
route, err = ds.GetRoute(testRoute.AppName, testRoute.Path)
|
||||||
|
if err != models.ErrRoutesNotFound {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test GetRoute: expected error `%v`, but it was `%v`", models.ErrRoutesNotFound, err)
|
||||||
|
}
|
||||||
|
if route != nil {
|
||||||
|
t.Log(buf.String())
|
||||||
|
t.Fatalf("Test RemoveApp: failed to remove the route")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ var (
|
|||||||
ErrAppsRemoving = errors.New("Could not remove app from datastore")
|
ErrAppsRemoving = errors.New("Could not remove app from datastore")
|
||||||
ErrAppsGet = errors.New("Could not get app from datastore")
|
ErrAppsGet = errors.New("Could not get app from datastore")
|
||||||
ErrAppsList = errors.New("Could not list apps from datastore")
|
ErrAppsList = errors.New("Could not list apps from datastore")
|
||||||
|
ErrAppsAlreadyExists = errors.New("App already exists")
|
||||||
ErrAppsNotFound = errors.New("App not found")
|
ErrAppsNotFound = errors.New("App not found")
|
||||||
ErrAppsNothingToUpdate = errors.New("Nothing to update")
|
ErrAppsNothingToUpdate = errors.New("Nothing to update")
|
||||||
ErrAppsMissingNew = errors.New("Missing new application")
|
ErrAppsMissingNew = errors.New("Missing new application")
|
||||||
|
|||||||
@@ -5,13 +5,15 @@ import "errors"
|
|||||||
type Datastore interface {
|
type Datastore interface {
|
||||||
GetApp(appName string) (*App, error)
|
GetApp(appName string) (*App, error)
|
||||||
GetApps(*AppFilter) ([]*App, error)
|
GetApps(*AppFilter) ([]*App, error)
|
||||||
StoreApp(*App) (*App, error)
|
InsertApp(app *App) (*App, error)
|
||||||
|
UpdateApp(app *App) (*App, error)
|
||||||
RemoveApp(appName string) error
|
RemoveApp(appName string) error
|
||||||
|
|
||||||
GetRoute(appName, routePath string) (*Route, error)
|
GetRoute(appName, routePath string) (*Route, error)
|
||||||
GetRoutes(*RouteFilter) (routes []*Route, err error)
|
GetRoutes(*RouteFilter) (routes []*Route, err error)
|
||||||
GetRoutesByApp(string, *RouteFilter) (routes []*Route, err error)
|
GetRoutesByApp(string, *RouteFilter) (routes []*Route, err error)
|
||||||
StoreRoute(*Route) (*Route, error)
|
InsertRoute(route *Route) (*Route, error)
|
||||||
|
UpdateRoute(route *Route) (*Route, error)
|
||||||
RemoveRoute(appName, routePath string) error
|
RemoveRoute(appName, routePath string) error
|
||||||
|
|
||||||
// The following provide a generic key value store for arbitrary data, can be used by extensions to store extra data
|
// The following provide a generic key value store for arbitrary data, can be used by extensions to store extra data
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ var (
|
|||||||
ErrRoutesRemoving = errors.New("Could not remove route from datastore")
|
ErrRoutesRemoving = errors.New("Could not remove route from datastore")
|
||||||
ErrRoutesGet = errors.New("Could not get route from datastore")
|
ErrRoutesGet = errors.New("Could not get route from datastore")
|
||||||
ErrRoutesList = errors.New("Could not list routes from datastore")
|
ErrRoutesList = errors.New("Could not list routes from datastore")
|
||||||
|
ErrRoutesAlreadyExists = errors.New("Route already exists")
|
||||||
ErrRoutesNotFound = errors.New("Route not found")
|
ErrRoutesNotFound = errors.New("Route not found")
|
||||||
ErrRoutesMissingNew = errors.New("Missing new route")
|
ErrRoutesMissingNew = errors.New("Missing new route")
|
||||||
ErrInvalidPayload = errors.New("Invalid payload")
|
ErrInvalidPayload = errors.New("Invalid payload")
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func handleAppCreate(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = Api.Datastore.StoreApp(wapp.App)
|
_, err = Api.Datastore.InsertApp(wapp.App)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Errorln(models.ErrAppsCreate)
|
log.WithError(err).Errorln(models.ErrAppsCreate)
|
||||||
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsCreate))
|
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsCreate))
|
||||||
|
|||||||
@@ -26,28 +26,29 @@ func setLogBuffer() *bytes.Buffer {
|
|||||||
|
|
||||||
func TestAppCreate(t *testing.T) {
|
func TestAppCreate(t *testing.T) {
|
||||||
buf := setLogBuffer()
|
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 {
|
for i, test := range []struct {
|
||||||
|
mock *datastore.Mock
|
||||||
path string
|
path string
|
||||||
body string
|
body string
|
||||||
expectedCode int
|
expectedCode int
|
||||||
expectedError error
|
expectedError error
|
||||||
}{
|
}{
|
||||||
// errors
|
// errors
|
||||||
{"/v1/apps", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
{&datastore.Mock{}, "/v1/apps", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
||||||
{"/v1/apps", `{}`, http.StatusBadRequest, models.ErrAppsMissingNew},
|
{&datastore.Mock{}, "/v1/apps", `{}`, http.StatusBadRequest, models.ErrAppsMissingNew},
|
||||||
{"/v1/apps", `{ "name": "Test" }`, http.StatusBadRequest, models.ErrAppsMissingNew},
|
{&datastore.Mock{}, "/v1/apps", `{ "name": "Test" }`, http.StatusBadRequest, models.ErrAppsMissingNew},
|
||||||
{"/v1/apps", `{ "app": { "name": "" } }`, http.StatusInternalServerError, models.ErrAppsValidationMissingName},
|
{&datastore.Mock{}, "/v1/apps", `{ "app": { "name": "" } }`, http.StatusInternalServerError, models.ErrAppsValidationMissingName},
|
||||||
{"/v1/apps", `{ "app": { "name": "1234567890123456789012345678901" } }`, http.StatusInternalServerError, models.ErrAppsValidationTooLongName},
|
{&datastore.Mock{}, "/v1/apps", `{ "app": { "name": "1234567890123456789012345678901" } }`, http.StatusInternalServerError, models.ErrAppsValidationTooLongName},
|
||||||
{"/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
|
{&datastore.Mock{}, "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
|
||||||
{"/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
|
{&datastore.Mock{}, "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
|
||||||
|
|
||||||
// success
|
// 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))
|
body := bytes.NewBuffer([]byte(test.body))
|
||||||
_, rec := routerRequest(t, router, "POST", test.path, body)
|
_, rec := routerRequest(t, router, "POST", test.path, body)
|
||||||
|
|
||||||
@@ -171,21 +172,27 @@ func TestAppGet(t *testing.T) {
|
|||||||
|
|
||||||
func TestAppUpdate(t *testing.T) {
|
func TestAppUpdate(t *testing.T) {
|
||||||
buf := setLogBuffer()
|
buf := setLogBuffer()
|
||||||
s := New(&datastore.Mock{}, &mqs.Mock{}, testRunner(t))
|
|
||||||
router := testRouter(s)
|
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
|
mock *datastore.Mock
|
||||||
path string
|
path string
|
||||||
body string
|
body string
|
||||||
expectedCode int
|
expectedCode int
|
||||||
expectedError error
|
expectedError error
|
||||||
}{
|
}{
|
||||||
// errors
|
// errors
|
||||||
{"/v1/apps/myapp", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
{&datastore.Mock{}, "/v1/apps/myapp", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
||||||
|
|
||||||
// success
|
// 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))
|
body := bytes.NewBuffer([]byte(test.body))
|
||||||
_, rec := routerRequest(t, router, "PUT", test.path, body)
|
_, rec := routerRequest(t, router, "PUT", test.path, body)
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ func handleAppUpdate(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app, err := Api.Datastore.StoreApp(wapp.App)
|
app, err := Api.Datastore.UpdateApp(wapp.App)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Debug(models.ErrAppsCreate)
|
log.WithError(err).Debug(models.ErrAppsUpdate)
|
||||||
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsCreate))
|
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsUpdate))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ func handleRouteCreate(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if app == nil {
|
if app == nil {
|
||||||
|
// Create a new application and add the route to that new application
|
||||||
newapp := &models.App{Name: wroute.Route.AppName}
|
newapp := &models.App{Name: wroute.Route.AppName}
|
||||||
if err := newapp.Validate(); err != nil {
|
if err := newapp.Validate(); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
@@ -60,7 +61,7 @@ func handleRouteCreate(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app, err = Api.Datastore.StoreApp(newapp)
|
app, err = Api.Datastore.InsertApp(newapp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Error(models.ErrAppsCreate)
|
log.WithError(err).Error(models.ErrAppsCreate)
|
||||||
c.JSON(http.StatusInternalServerError, simpleError(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 {
|
if err != nil {
|
||||||
log.WithError(err).Error(models.ErrRoutesCreate)
|
log.WithError(err).Error(models.ErrRoutesCreate)
|
||||||
c.JSON(http.StatusInternalServerError, simpleError(models.ErrRoutesCreate))
|
c.JSON(http.StatusInternalServerError, simpleError(models.ErrRoutesCreate))
|
||||||
|
|||||||
@@ -13,27 +13,29 @@ import (
|
|||||||
|
|
||||||
func TestRouteCreate(t *testing.T) {
|
func TestRouteCreate(t *testing.T) {
|
||||||
buf := setLogBuffer()
|
buf := setLogBuffer()
|
||||||
s := New(&datastore.Mock{}, &mqs.Mock{}, testRunner(t))
|
|
||||||
router := testRouter(s)
|
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
|
mock *datastore.Mock
|
||||||
path string
|
path string
|
||||||
body string
|
body string
|
||||||
expectedCode int
|
expectedCode int
|
||||||
expectedError error
|
expectedError error
|
||||||
}{
|
}{
|
||||||
// errors
|
// errors
|
||||||
{"/v1/apps/a/routes", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
{&datastore.Mock{}, "/v1/apps/a/routes", ``, http.StatusBadRequest, models.ErrInvalidJSON},
|
||||||
{"/v1/apps/a/routes", `{ }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
{&datastore.Mock{}, "/v1/apps/a/routes", `{ }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
||||||
{"/v1/apps/a/routes", `{ "path": "/myroute" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
{&datastore.Mock{}, "/v1/apps/a/routes", `{ "path": "/myroute" }`, http.StatusBadRequest, models.ErrRoutesMissingNew},
|
||||||
{"/v1/apps/a/routes", `{ "route": { } }`, http.StatusInternalServerError, models.ErrRoutesValidationMissingImage},
|
{&datastore.Mock{}, "/v1/apps/a/routes", `{ "route": { } }`, http.StatusInternalServerError, models.ErrRoutesValidationMissingImage},
|
||||||
{"/v1/apps/a/routes", `{ "route": { "image": "iron/hello" } }`, http.StatusInternalServerError, models.ErrRoutesValidationMissingPath},
|
{&datastore.Mock{}, "/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},
|
{&datastore.Mock{}, "/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/$/routes", `{ "route": { "image": "iron/hello", "path": "/myroute" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
|
||||||
|
|
||||||
// success
|
// 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))
|
body := bytes.NewBuffer([]byte(test.body))
|
||||||
_, rec := routerRequest(t, router, "POST", test.path, body)
|
_, rec := routerRequest(t, router, "POST", test.path, body)
|
||||||
|
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ func handleRouteUpdate(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = Api.Datastore.StoreRoute(wroute.Route)
|
_, err = Api.Datastore.UpdateRoute(wroute.Route)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Debug(models.ErrAppsCreate)
|
log.WithError(err).Debug(models.ErrRoutesUpdate)
|
||||||
c.JSON(http.StatusInternalServerError, simpleError(models.ErrAppsCreate))
|
c.JSON(http.StatusInternalServerError, simpleError(models.ErrRoutesUpdate))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -92,7 +91,6 @@ func TestRouteRunnerPost(t *testing.T) {
|
|||||||
resp := getErrorResponse(t, rec)
|
resp := getErrorResponse(t, rec)
|
||||||
respMsg := resp.Error.Message
|
respMsg := resp.Error.Message
|
||||||
expMsg := test.expectedError.Error()
|
expMsg := test.expectedError.Error()
|
||||||
fmt.Println(respMsg == expMsg)
|
|
||||||
if respMsg != expMsg && !strings.Contains(respMsg, expMsg) {
|
if respMsg != expMsg && !strings.Contains(respMsg, expMsg) {
|
||||||
t.Log(buf.String())
|
t.Log(buf.String())
|
||||||
t.Errorf("Test %d: Expected error message to have `%s`",
|
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 {
|
for j, param := range test.expectedParams {
|
||||||
if params[j].Key != param.Key || params[j].Value != param.Value {
|
if params[j].Key != param.Key || params[j].Value != param.Value {
|
||||||
t.Log(buf.String())
|
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)
|
t.Errorf("Test %d: expected param %d, key = %s, value = %s", i, j, param.Key, param.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package server
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
@@ -185,6 +186,8 @@ func (s *Server) bindHandlers() {
|
|||||||
engine.NoRoute(handleSpecial)
|
engine.NoRoute(handleSpecial)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErrInternalServerError = errors.New("Something unexpected happened on the server")
|
||||||
|
|
||||||
func simpleError(err error) *models.Error {
|
func simpleError(err error) *models.Error {
|
||||||
return &models.Error{&models.ErrorBody{Message: err.Error()}}
|
return &models.Error{&models.ErrorBody{Message: err.Error()}}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ func getErrorResponse(t *testing.T, rec *httptest.ResponseRecorder) models.Error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func prepareBolt(t *testing.T) (models.Datastore, func()) {
|
func prepareBolt(t *testing.T) (models.Datastore, func()) {
|
||||||
|
os.Remove(tmpBolt)
|
||||||
ds, err := datastore.New("bolt://" + tmpBolt)
|
ds, err := datastore.New("bolt://" + tmpBolt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Error when creating datastore: %s", err)
|
t.Fatal("Error when creating datastore: %s", err)
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ test:
|
|||||||
override:
|
override:
|
||||||
- make test-docker:
|
- make test-docker:
|
||||||
pwd: $GO_PROJECT
|
pwd: $GO_PROJECT
|
||||||
|
- make test-datastore:
|
||||||
|
pwd: $GO_PROJECT
|
||||||
|
|
||||||
deployment:
|
deployment:
|
||||||
release:
|
release:
|
||||||
|
|||||||
Reference in New Issue
Block a user