github.com/iron-io/functions@v0.0.0-20180820112432-d59d7d1c40b2/api/datastore/internal/datastoretest/test.go (about) 1 package datastoretest 2 3 import ( 4 "bytes" 5 "context" 6 "log" 7 "testing" 8 9 "github.com/iron-io/functions/api/models" 10 11 "net/http" 12 "net/url" 13 "os" 14 "reflect" 15 16 "github.com/Sirupsen/logrus" 17 "github.com/gin-gonic/gin" 18 ) 19 20 func setLogBuffer() *bytes.Buffer { 21 var buf bytes.Buffer 22 buf.WriteByte('\n') 23 logrus.SetOutput(&buf) 24 gin.DefaultErrorWriter = &buf 25 gin.DefaultWriter = &buf 26 log.SetOutput(&buf) 27 return &buf 28 } 29 30 func GetContainerHostIP() string { 31 dockerHost := os.Getenv("DOCKER_HOST") 32 if dockerHost == "" { 33 return "127.0.0.1" 34 } 35 parts, _ := url.Parse(dockerHost) 36 return parts.Hostname() 37 } 38 39 func Test(t *testing.T, ds models.Datastore) { 40 buf := setLogBuffer() 41 42 ctx := context.Background() 43 44 t.Run("apps", func(t *testing.T) { 45 // Testing insert app 46 _, err := ds.InsertApp(ctx, nil) 47 if err != models.ErrDatastoreEmptyApp { 48 t.Log(buf.String()) 49 t.Fatalf("Test InsertApp(nil): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyApp, err) 50 } 51 52 _, err = ds.InsertApp(ctx, &models.App{}) 53 if err != models.ErrDatastoreEmptyAppName { 54 t.Log(buf.String()) 55 t.Fatalf("Test InsertApp(&{}): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err) 56 } 57 58 inserted, err := ds.InsertApp(ctx, testApp) 59 if err != nil { 60 t.Log(buf.String()) 61 t.Fatalf("Test InsertApp: error when storing new app: %s", err) 62 } 63 if !reflect.DeepEqual(*inserted, *testApp) { 64 t.Log(buf.String()) 65 t.Fatalf("Test InsertApp: expected to insert:\n%v\nbut got:\n%v", testApp, inserted) 66 } 67 68 _, err = ds.InsertApp(ctx, testApp) 69 if err != models.ErrAppsAlreadyExists { 70 t.Log(buf.String()) 71 t.Fatalf("Test InsertApp duplicated: expected error `%v`, but it was `%v`", models.ErrAppsAlreadyExists, err) 72 } 73 74 { 75 // Set a config var 76 updated, err := ds.UpdateApp(ctx, 77 &models.App{Name: testApp.Name, Config: map[string]string{"TEST": "1"}}) 78 if err != nil { 79 t.Log(buf.String()) 80 t.Fatalf("Test UpdateApp: error when updating app: %v", err) 81 } 82 expected := &models.App{Name: testApp.Name, Config: map[string]string{"TEST": "1"}} 83 if !reflect.DeepEqual(*updated, *expected) { 84 t.Log(buf.String()) 85 t.Fatalf("Test UpdateApp: expected updated `%v` but got `%v`", expected, updated) 86 } 87 88 // Set a different var (without clearing the existing) 89 updated, err = ds.UpdateApp(ctx, 90 &models.App{Name: testApp.Name, Config: map[string]string{"OTHER": "TEST"}}) 91 if err != nil { 92 t.Log(buf.String()) 93 t.Fatalf("Test UpdateApp: error when updating app: %v", err) 94 } 95 expected = &models.App{Name: testApp.Name, Config: map[string]string{"TEST": "1", "OTHER": "TEST"}} 96 if !reflect.DeepEqual(*updated, *expected) { 97 t.Log(buf.String()) 98 t.Fatalf("Test UpdateApp: expected updated `%v` but got `%v`", expected, updated) 99 } 100 101 // Delete a var 102 updated, err = ds.UpdateApp(ctx, 103 &models.App{Name: testApp.Name, Config: map[string]string{"TEST": ""}}) 104 if err != nil { 105 t.Log(buf.String()) 106 t.Fatalf("Test UpdateApp: error when updating app: %v", err) 107 } 108 expected = &models.App{Name: testApp.Name, Config: map[string]string{"OTHER": "TEST"}} 109 if !reflect.DeepEqual(*updated, *expected) { 110 t.Log(buf.String()) 111 t.Fatalf("Test UpdateApp: expected updated `%v` but got `%v`", expected, updated) 112 } 113 } 114 115 // Testing get app 116 _, err = ds.GetApp(ctx, "") 117 if err != models.ErrDatastoreEmptyAppName { 118 t.Log(buf.String()) 119 t.Fatalf("Test GetApp: expected error to be %v, but it was %s", models.ErrDatastoreEmptyAppName, err) 120 } 121 122 app, err := ds.GetApp(ctx, testApp.Name) 123 if err != nil { 124 t.Log(buf.String()) 125 t.Fatalf("Test GetApp: error: %s", err) 126 } 127 if app.Name != testApp.Name { 128 t.Log(buf.String()) 129 t.Fatalf("Test GetApp: expected `app.Name` to be `%s` but it was `%s`", app.Name, testApp.Name) 130 } 131 132 // Testing list apps 133 apps, err := ds.GetApps(ctx, &models.AppFilter{}) 134 if err != nil { 135 t.Log(buf.String()) 136 t.Fatalf("Test GetApps: unexpected error %v", err) 137 } 138 if len(apps) == 0 { 139 t.Fatal("Test GetApps: expected result count to be greater than 0") 140 } 141 if apps[0].Name != testApp.Name { 142 t.Log(buf.String()) 143 t.Fatalf("Test GetApps: expected `app.Name` to be `%s` but it was `%s`", app.Name, testApp.Name) 144 } 145 146 apps, err = ds.GetApps(ctx, &models.AppFilter{Name: "Tes%"}) 147 if err != nil { 148 t.Log(buf.String()) 149 t.Fatalf("Test GetApps(filter): unexpected error %v", err) 150 } 151 if len(apps) == 0 { 152 t.Fatal("Test GetApps(filter): expected result count to be greater than 0") 153 } 154 155 // Testing app delete 156 err = ds.RemoveApp(ctx, "") 157 if err != models.ErrDatastoreEmptyAppName { 158 t.Log(buf.String()) 159 t.Fatalf("Test RemoveApp: expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err) 160 } 161 162 err = ds.RemoveApp(ctx, testApp.Name) 163 if err != nil { 164 t.Log(buf.String()) 165 t.Fatalf("Test RemoveApp: error: %s", err) 166 } 167 app, err = ds.GetApp(ctx, testApp.Name) 168 if err != models.ErrAppsNotFound { 169 t.Log(buf.String()) 170 t.Fatalf("Test GetApp(removed): expected error `%v`, but it was `%v`", models.ErrAppsNotFound, err) 171 } 172 if app != nil { 173 t.Log(buf.String()) 174 t.Fatal("Test RemoveApp: failed to remove the app") 175 } 176 177 // Test update inexistent app 178 _, err = ds.UpdateApp(ctx, &models.App{ 179 Name: testApp.Name, 180 Config: map[string]string{ 181 "TEST": "1", 182 }, 183 }) 184 if err != models.ErrAppsNotFound { 185 t.Log(buf.String()) 186 t.Fatalf("Test UpdateApp(inexistent): expected error `%v`, but it was `%v`", models.ErrAppsNotFound, err) 187 } 188 }) 189 190 t.Run("routes", func(t *testing.T) { 191 // Insert app again to test routes 192 _, err := ds.InsertApp(ctx, testApp) 193 if err != nil && err != models.ErrAppsAlreadyExists { 194 t.Log(buf.String()) 195 t.Fatalf("Test InsertRoute Prep: failed to insert app: ", err) 196 } 197 198 // Testing insert route 199 { 200 _, err = ds.InsertRoute(ctx, nil) 201 if err != models.ErrDatastoreEmptyRoute { 202 t.Log(buf.String()) 203 t.Fatalf("Test InsertRoute(nil): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyRoute, err) 204 } 205 206 _, err = ds.InsertRoute(ctx, &models.Route{AppName: "notreal", Path: "/test"}) 207 if err != models.ErrAppsNotFound { 208 t.Log(buf.String()) 209 t.Fatalf("Test InsertRoute: expected error `%v`, but it was `%v`", models.ErrAppsNotFound, err) 210 } 211 212 _, err = ds.InsertRoute(ctx, testRoute) 213 if err != nil { 214 t.Log(buf.String()) 215 t.Fatalf("Test InsertRoute: error when storing new route: %s", err) 216 } 217 218 _, err = ds.InsertRoute(ctx, testRoute) 219 if err != models.ErrRoutesAlreadyExists { 220 t.Log(buf.String()) 221 t.Fatalf("Test InsertRoute duplicated: expected error to be `%v`, but it was `%v`", models.ErrRoutesAlreadyExists, err) 222 } 223 } 224 225 // Testing get 226 { 227 _, err = ds.GetRoute(ctx, "a", "") 228 if err != models.ErrDatastoreEmptyRoutePath { 229 t.Log(buf.String()) 230 t.Fatalf("Test GetRoute(empty route path): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyRoutePath, err) 231 } 232 233 _, err = ds.GetRoute(ctx, "", "a") 234 if err != models.ErrDatastoreEmptyAppName { 235 t.Log(buf.String()) 236 t.Fatalf("Test GetRoute(empty app name): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err) 237 } 238 239 route, err := ds.GetRoute(ctx, testApp.Name, testRoute.Path) 240 if err != nil { 241 t.Log(buf.String()) 242 t.Fatalf("Test GetRoute: unexpected error %v", err) 243 } 244 var expected models.Route = *testRoute 245 if !reflect.DeepEqual(*route, expected) { 246 t.Log(buf.String()) 247 t.Fatalf("Test InsertApp: expected to insert:\n%v\nbut got:\n%v", expected, route) 248 } 249 } 250 251 // Testing update 252 { 253 // Update some fields, and add 3 configs and 3 headers. 254 updated, err := ds.UpdateRoute(ctx, &models.Route{ 255 AppName: testRoute.AppName, 256 Path: testRoute.Path, 257 Timeout: 100, 258 Config: map[string]string{ 259 "FIRST": "1", 260 "SECOND": "2", 261 "THIRD": "3", 262 }, 263 Headers: http.Header{ 264 "First": []string{"test"}, 265 "Second": []string{"test", "test"}, 266 "Third": []string{"test", "test2"}, 267 }, 268 }) 269 if err != nil { 270 t.Log(buf.String()) 271 t.Fatalf("Test UpdateRoute: unexpected error: %v", err) 272 } 273 expected := &models.Route{ 274 // unchanged 275 AppName: testRoute.AppName, 276 Path: testRoute.Path, 277 Image: "iron/hello", 278 Type: "sync", 279 Format: "http", 280 // updated 281 Timeout: 100, 282 Config: map[string]string{ 283 "FIRST": "1", 284 "SECOND": "2", 285 "THIRD": "3", 286 }, 287 Headers: http.Header{ 288 "First": []string{"test"}, 289 "Second": []string{"test", "test"}, 290 "Third": []string{"test", "test2"}, 291 }, 292 } 293 if !reflect.DeepEqual(*updated, *expected) { 294 t.Log(buf.String()) 295 t.Fatalf("Test UpdateRoute: expected updated `%v` but got `%v`", expected, updated) 296 } 297 298 // Update a config var, remove another. Add one Header, remove another. 299 updated, err = ds.UpdateRoute(ctx, &models.Route{ 300 AppName: testRoute.AppName, 301 Path: testRoute.Path, 302 Config: map[string]string{ 303 "FIRST": "first", 304 "SECOND": "", 305 "THIRD": "3", 306 }, 307 Headers: http.Header{ 308 "First": []string{"test2"}, 309 "Second": nil, 310 }, 311 }) 312 if err != nil { 313 t.Log(buf.String()) 314 t.Fatalf("Test UpdateRoute: unexpected error: %v", err) 315 } 316 expected = &models.Route{ 317 // unchanged 318 AppName: testRoute.AppName, 319 Path: testRoute.Path, 320 Image: "iron/hello", 321 Type: "sync", 322 Format: "http", 323 Timeout: 100, 324 // updated 325 Config: map[string]string{ 326 "FIRST": "first", 327 "THIRD": "3", 328 }, 329 Headers: http.Header{ 330 "First": []string{"test", "test2"}, 331 "Third": []string{"test", "test2"}, 332 }, 333 } 334 if !reflect.DeepEqual(*updated, *expected) { 335 t.Log(buf.String()) 336 t.Fatalf("Test UpdateRoute: expected updated:\n`%v`\nbut got:\n`%v`", expected, updated) 337 } 338 } 339 340 // Testing list routes 341 routes, err := ds.GetRoutesByApp(ctx, testApp.Name, &models.RouteFilter{}) 342 if err != nil { 343 t.Log(buf.String()) 344 t.Fatalf("Test GetRoutesByApp: unexpected error %v", err) 345 } 346 if len(routes) == 0 { 347 t.Fatal("Test GetRoutesByApp: expected result count to be greater than 0") 348 } 349 if routes[0] == nil { 350 t.Log(buf.String()) 351 t.Fatalf("Test GetRoutes: expected non-nil route") 352 } else if routes[0].Path != testRoute.Path { 353 t.Log(buf.String()) 354 t.Fatalf("Test GetRoutes: expected `app.Name` to be `%s` but it was `%s`", testRoute.Path, routes[0].Path) 355 } 356 357 routes, err = ds.GetRoutesByApp(ctx, testApp.Name, &models.RouteFilter{Image: testRoute.Image}) 358 if err != nil { 359 t.Log(buf.String()) 360 t.Fatalf("Test GetRoutesByApp: unexpected error %v", err) 361 } 362 if len(routes) == 0 { 363 t.Fatal("Test GetRoutesByApp: expected result count to be greater than 0") 364 } 365 if routes[0] == nil { 366 t.Log(buf.String()) 367 t.Fatalf("Test GetRoutes: expected non-nil route") 368 } else if routes[0].Path != testRoute.Path { 369 t.Log(buf.String()) 370 t.Fatalf("Test GetRoutes: expected `app.Name` to be `%s` but it was `%s`", testRoute.Path, routes[0].Path) 371 } 372 373 routes, err = ds.GetRoutesByApp(ctx, "notreal", nil) 374 if err != nil { 375 t.Log(buf.String()) 376 t.Fatalf("Test GetRoutesByApp: error: %s", err) 377 } 378 if len(routes) != 0 { 379 t.Fatalf("Test GetRoutesByApp: expected result count to be 0 but got %d", len(routes)) 380 } 381 382 // Testing list routes 383 routes, err = ds.GetRoutes(ctx, &models.RouteFilter{Image: testRoute.Image}) 384 if err != nil { 385 t.Log(buf.String()) 386 t.Fatalf("Test GetRoutes: error: %s", err) 387 } 388 if len(routes) == 0 { 389 t.Fatal("Test GetRoutes: expected result count to be greater than 0") 390 } 391 if routes[0].Path != testRoute.Path { 392 t.Log(buf.String()) 393 t.Fatalf("Test GetRoutes: expected `app.Name` to be `%s` but it was `%s`", testRoute.Path, routes[0].Path) 394 } 395 396 // Testing route delete 397 err = ds.RemoveRoute(ctx, "", "") 398 if err != models.ErrDatastoreEmptyAppName { 399 t.Log(buf.String()) 400 t.Fatalf("Test RemoveRoute(empty app name): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyAppName, err) 401 } 402 403 err = ds.RemoveRoute(ctx, "a", "") 404 if err != models.ErrDatastoreEmptyRoutePath { 405 t.Log(buf.String()) 406 t.Fatalf("Test RemoveRoute(empty route path): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyRoutePath, err) 407 } 408 409 err = ds.RemoveRoute(ctx, testRoute.AppName, testRoute.Path) 410 if err != nil { 411 t.Log(buf.String()) 412 t.Fatalf("Test RemoveApp: unexpected error: %v", err) 413 } 414 415 route, err := ds.GetRoute(ctx, testRoute.AppName, testRoute.Path) 416 if err != nil && err != models.ErrRoutesNotFound { 417 t.Log(buf.String()) 418 t.Fatalf("Test GetRoute: expected error `%v`, but it was `%v`", models.ErrRoutesNotFound, err) 419 } 420 if route != nil { 421 t.Log(buf.String()) 422 t.Fatalf("Test RemoveApp: failed to remove the route: %v", route) 423 } 424 425 _, err = ds.UpdateRoute(ctx, &models.Route{ 426 AppName: testRoute.AppName, 427 Path: testRoute.Path, 428 Image: "test", 429 }) 430 if err != models.ErrRoutesNotFound { 431 t.Log(buf.String()) 432 t.Fatalf("Test UpdateRoute inexistent: expected error to be `%v`, but it was `%v`", models.ErrRoutesNotFound, err) 433 } 434 }) 435 436 t.Run("put-get", func(t *testing.T) { 437 // Testing Put/Get 438 err := ds.Put(ctx, nil, nil) 439 if err != models.ErrDatastoreEmptyKey { 440 t.Log(buf.String()) 441 t.Fatalf("Test Put(nil,nil): expected error `%v`, but it was `%v`", models.ErrDatastoreEmptyKey, err) 442 } 443 444 err = ds.Put(ctx, []byte("test"), []byte("success")) 445 if err != nil { 446 t.Log(buf.String()) 447 t.Fatalf("Test Put: unexpected error: %v", err) 448 } 449 450 val, err := ds.Get(ctx, []byte("test")) 451 if err != nil { 452 t.Log(buf.String()) 453 t.Fatalf("Test Put: unexpected error: %v", err) 454 } 455 if string(val) != "success" { 456 t.Log(buf.String()) 457 t.Fatalf("Test Get: expected value to be `%v`, but it was `%v`", "success", string(val)) 458 } 459 460 err = ds.Put(ctx, []byte("test"), nil) 461 if err != nil { 462 t.Log(buf.String()) 463 t.Fatalf("Test Put: unexpected error: %v", err) 464 } 465 466 val, err = ds.Get(ctx, []byte("test")) 467 if err != nil { 468 t.Log(buf.String()) 469 t.Fatalf("Test Put: unexpected error: %v", err) 470 } 471 if string(val) != "" { 472 t.Log(buf.String()) 473 t.Fatalf("Test Get: expected value to be `%v`, but it was `%v`", "", string(val)) 474 } 475 }) 476 } 477 478 var testApp = &models.App{ 479 Name: "Test", 480 } 481 482 var testRoute = &models.Route{ 483 AppName: testApp.Name, 484 Path: "/test", 485 Image: "iron/hello", 486 Type: "sync", 487 Format: "http", 488 }