mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
* datastore no longer implements logstore the underlying implementation of our sql store implements both the datastore and the logstore interface, however going forward we are likely to encounter datastore implementers that would mock out the logstore interface and not use its methods - signalling a poor interface. this remedies that, now they are 2 completely separate things, which our sqlstore happens to implement both of. related to some recent changes around wrapping, this keeps the imposed metrics and validation wrapping of a servers logstore and datastore, just moving it into New instead of in the opts - this is so that a user can have the underlying datastore in order to set the logstore to it, since wrapping it in a validator/metrics would render it no longer a logstore implementer (i.e. validate datastore doesn't implement the logstore interface), we need to do this after setting the logstore to the datastore if one wasn't provided explicitly. * splits logstore and datastore metrics & validation logic * `make test` should be `make full-test` always. got rid of that so that nobody else has to wait for CI to blow up on them after the tests pass locally ever again. * fix new tests
162 lines
3.5 KiB
Go
162 lines
3.5 KiB
Go
package sql
|
|
|
|
import (
|
|
"context"
|
|
"net/url"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/fnproject/fn/api/datastore/internal/datastoretest"
|
|
"github.com/fnproject/fn/api/datastore/internal/datastoreutil"
|
|
"github.com/fnproject/fn/api/datastore/sql/migratex"
|
|
"github.com/fnproject/fn/api/datastore/sql/migrations"
|
|
logstoretest "github.com/fnproject/fn/api/logs/testing"
|
|
"github.com/fnproject/fn/api/models"
|
|
"github.com/jmoiron/sqlx"
|
|
)
|
|
|
|
// since New with fresh dbs skips all migrations:
|
|
// * open a fresh db on latest version
|
|
// * run all down migrations
|
|
// * run all up migrations
|
|
// [ then run tests against that db ]
|
|
func newWithMigrations(ctx context.Context, url *url.URL) (*SQLStore, error) {
|
|
ds, err := newDS(ctx, url)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = ds.Tx(func(tx *sqlx.Tx) error {
|
|
return migratex.Down(ctx, tx, migrations.Migrations)
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// go through New, to ensure our Up logic works in there...
|
|
ds, err = newDS(ctx, url)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ds, nil
|
|
}
|
|
|
|
func TestDatastore(t *testing.T) {
|
|
ctx := context.Background()
|
|
defer os.RemoveAll("sqlite_test_dir")
|
|
u, err := url.Parse("sqlite3://sqlite_test_dir")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
f := func(t *testing.T) *SQLStore {
|
|
os.RemoveAll("sqlite_test_dir")
|
|
ds, err := newDS(ctx, u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// we don't want to test the validator, really
|
|
return ds
|
|
}
|
|
f2 := func(t *testing.T) models.Datastore {
|
|
ds := f(t)
|
|
return datastoreutil.NewValidator(ds)
|
|
}
|
|
datastoretest.Test(t, f2)
|
|
|
|
// also logs
|
|
logstoretest.Test(t, f(t))
|
|
|
|
// NOTE: sqlite3 does not like ALTER TABLE DROP COLUMN so do not run
|
|
// migration tests against it, only pg and mysql -- should prove UP migrations
|
|
// will likely work for sqlite3, but may need separate testing by devs :(
|
|
|
|
// if being run from test script (CI) poke around for pg and mysql containers
|
|
// to run tests against them too. this runs with a fresh db first run, then
|
|
// will down migrate all migrations, up migrate, and run tests again.
|
|
|
|
both := func(u *url.URL) {
|
|
f := func(t *testing.T) *SQLStore {
|
|
ds, err := newDS(ctx, u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ds.clear()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return ds
|
|
}
|
|
f2 := func(t *testing.T) models.Datastore {
|
|
ds := f(t)
|
|
return datastoreutil.NewValidator(ds)
|
|
}
|
|
|
|
// test fresh w/o migrations
|
|
datastoretest.Test(t, f2)
|
|
|
|
// also test sql implements logstore
|
|
logstoretest.Test(t, f(t))
|
|
|
|
f = func(t *testing.T) *SQLStore {
|
|
t.Log("with migrations now!")
|
|
ds, err := newWithMigrations(ctx, u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ds.clear()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return ds
|
|
}
|
|
f2 = func(t *testing.T) models.Datastore {
|
|
ds := f(t)
|
|
return datastoreutil.NewValidator(ds)
|
|
}
|
|
|
|
// test that migrations work & things work with them
|
|
datastoretest.Test(t, f2)
|
|
|
|
// also test sql implements logstore
|
|
logstoretest.Test(t, f(t))
|
|
}
|
|
|
|
if pg := os.Getenv("POSTGRES_URL"); pg != "" {
|
|
u, err := url.Parse(pg)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
both(u)
|
|
}
|
|
|
|
if mysql := os.Getenv("MYSQL_URL"); mysql != "" {
|
|
u, err := url.Parse(mysql)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
both(u)
|
|
}
|
|
|
|
}
|
|
|
|
func TestClose(t *testing.T) {
|
|
ctx := context.Background()
|
|
defer os.RemoveAll("sqlite_test_dir")
|
|
u, err := url.Parse("sqlite3://sqlite_test_dir")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
os.RemoveAll("sqlite_test_dir")
|
|
ds, err := newDS(ctx, u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := ds.Close(); err != nil {
|
|
t.Fatalf("Failed to close datastore: %v", err)
|
|
}
|
|
}
|