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

runs Postgres tests with all 4 latest versions #1549

Merged
merged 1 commit into from
Sep 27, 2023
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
98 changes: 60 additions & 38 deletions internal/datastore/postgres/postgres_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"github.com/authzed/spicedb/internal/datastore/common"
pgcommon "github.com/authzed/spicedb/internal/datastore/postgres/common"
pgversion "github.com/authzed/spicedb/internal/datastore/postgres/version"
"github.com/authzed/spicedb/internal/testfixtures"
testdatastore "github.com/authzed/spicedb/internal/testserver/datastore"
"github.com/authzed/spicedb/pkg/datastore"
Expand All @@ -40,17 +41,36 @@ func (pgd *pgDatastore) ExampleRetryableError() error {
}
}

// the global OTel tracer is used everywhere, so we synchronize tests over a global test tracer
var (
otelMutex = sync.Mutex{}
testTraceProvider *trace.TracerProvider
)

func init() {
testTraceProvider = trace.NewTracerProvider(
trace.WithSampler(trace.AlwaysSample()),
)
otel.SetTracerProvider(testTraceProvider)
}

func TestPostgresDatastore(t *testing.T) {
t.Parallel()

for _, config := range []struct {
targetMigration string
migrationPhase string
pgVersion string
}{
{"head", ""},
{"head", "", pgversion.MinimumSupportedPostgresVersion},
{"head", "", "14"},
{"head", "", "15"},
{"head", "", "16"},
} {
config := config
t.Run(fmt.Sprintf("%s-%s", config.targetMigration, config.migrationPhase), func(t *testing.T) {
t.Run(fmt.Sprintf("postgres-%s-%s-%s", config.pgVersion, config.targetMigration, config.migrationPhase), func(t *testing.T) {
t.Parallel()
b := testdatastore.RunPostgresForTesting(t, "", config.targetMigration)
b := testdatastore.RunPostgresForTesting(t, "", config.targetMigration, config.pgVersion)

test.All(t, test.DatastoreTesterFunc(func(revisionQuantization, gcInterval, gcWindow time.Duration, watchBufferLength uint16) (datastore.Datastore, error) {
ds := b.NewDatastore(t, func(engine, uri string) datastore.Datastore {
Expand Down Expand Up @@ -109,11 +129,11 @@ func TestPostgresDatastore(t *testing.T) {
})

t.Run("WatchNotEnabled", func(t *testing.T) {
WatchNotEnabledTest(t, b)
WatchNotEnabledTest(t, b, config.pgVersion)
})

t.Run("GCQueriesServedByExpectedIndexes", func(t *testing.T) {
GCQueriesServedByExpectedIndexes(t, b)
GCQueriesServedByExpectedIndexes(t, b, config.pgVersion)
})

if config.migrationPhase == "" {
Expand Down Expand Up @@ -167,23 +187,32 @@ func TestPostgresDatastore(t *testing.T) {
}

func TestPostgresDatastoreWithoutCommitTimestamps(t *testing.T) {
b := testdatastore.RunPostgresForTestingWithCommitTimestamps(t, "", "head", false)
t.Parallel()

// NOTE: watch API requires the commit timestamps, so we skip those tests here.
test.AllWithExceptions(t, test.DatastoreTesterFunc(func(revisionQuantization, gcInterval, gcWindow time.Duration, watchBufferLength uint16) (datastore.Datastore, error) {
ds := b.NewDatastore(t, func(engine, uri string) datastore.Datastore {
ds, err := newPostgresDatastore(uri,
RevisionQuantization(revisionQuantization),
GCWindow(gcWindow),
GCInterval(gcInterval),
WatchBufferLength(watchBufferLength),
DebugAnalyzeBeforeStatistics(),
)
require.NoError(t, err)
return ds
for _, pgVersion := range []string{pgversion.MinimumSupportedPostgresVersion, "14", "15", "16"} {
pgVersion := pgVersion
t.Run(fmt.Sprintf("postgres-%s", pgVersion), func(t *testing.T) {
t.Parallel()

b := testdatastore.RunPostgresForTestingWithCommitTimestamps(t, "", "head", false, pgVersion)

// NOTE: watch API requires the commit timestamps, so we skip those tests here.
test.AllWithExceptions(t, test.DatastoreTesterFunc(func(revisionQuantization, gcInterval, gcWindow time.Duration, watchBufferLength uint16) (datastore.Datastore, error) {
ds := b.NewDatastore(t, func(engine, uri string) datastore.Datastore {
ds, err := newPostgresDatastore(uri,
RevisionQuantization(revisionQuantization),
GCWindow(gcWindow),
GCInterval(gcInterval),
WatchBufferLength(watchBufferLength),
DebugAnalyzeBeforeStatistics(),
)
require.NoError(t, err)
return ds
})
return ds, nil
}), test.WithCategories(test.WatchCategory))
})
return ds, nil
}), test.WithCategories(test.WatchCategory))
}
}

type datastoreTestFunc func(t *testing.T, ds datastore.Datastore)
Expand Down Expand Up @@ -1067,25 +1096,18 @@ func RevisionInversionTest(t *testing.T, ds datastore.Datastore) {
}

func OTelTracingTest(t *testing.T, ds datastore.Datastore) {
otelMutex.Lock()
defer otelMutex.Unlock()

require := require.New(t)

ctx := context.Background()
r, err := ds.ReadyState(ctx)
require.NoError(err)
require.True(r.IsReady)

// Setup OTel recording
defaultProvider := otel.GetTracerProvider()

provider := trace.NewTracerProvider(
trace.WithSampler(trace.AlwaysSample()),
)
spanrecorder := tracetest.NewSpanRecorder()
provider.RegisterSpanProcessor(spanrecorder)
otel.SetTracerProvider(provider)
defer func() {
otel.SetTracerProvider(defaultProvider)
}()
testTraceProvider.RegisterSpanProcessor(spanrecorder)

// Perform basic operation
_, err = ds.ReadWriteTx(ctx, func(rwt datastore.ReadWriteTransaction) error {
Expand All @@ -1103,10 +1125,10 @@ func OTelTracingTest(t *testing.T, ds datastore.Datastore) {
require.True(present, "missing trace for Streaming gRPC call")
}

func WatchNotEnabledTest(t *testing.T, _ testdatastore.RunningEngineForTest) {
func WatchNotEnabledTest(t *testing.T, _ testdatastore.RunningEngineForTest, pgVersion string) {
require := require.New(t)

ds := testdatastore.RunPostgresForTestingWithCommitTimestamps(t, "", migrate.Head, false).NewDatastore(t, func(engine, uri string) datastore.Datastore {
ds := testdatastore.RunPostgresForTestingWithCommitTimestamps(t, "", migrate.Head, false, pgVersion).NewDatastore(t, func(engine, uri string) datastore.Datastore {
ds, err := newPostgresDatastore(uri,
RevisionQuantization(0),
GCWindow(time.Millisecond*1),
Expand All @@ -1130,7 +1152,7 @@ func WatchNotEnabledTest(t *testing.T, _ testdatastore.RunningEngineForTest) {
func BenchmarkPostgresQuery(b *testing.B) {
req := require.New(b)

ds := testdatastore.RunPostgresForTesting(b, "", migrate.Head).NewDatastore(b, func(engine, uri string) datastore.Datastore {
ds := testdatastore.RunPostgresForTesting(b, "", migrate.Head, pgversion.MinimumSupportedPostgresVersion).NewDatastore(b, func(engine, uri string) datastore.Datastore {
ds, err := newPostgresDatastore(uri,
RevisionQuantization(0),
GCWindow(time.Millisecond*1),
Expand Down Expand Up @@ -1161,10 +1183,10 @@ func BenchmarkPostgresQuery(b *testing.B) {
})
}

func datastoreWithInterceptorAndTestData(t *testing.T, interceptor pgcommon.QueryInterceptor) datastore.Datastore {
func datastoreWithInterceptorAndTestData(t *testing.T, interceptor pgcommon.QueryInterceptor, pgVersion string) datastore.Datastore {
require := require.New(t)

ds := testdatastore.RunPostgresForTestingWithCommitTimestamps(t, "", migrate.Head, false).NewDatastore(t, func(engine, uri string) datastore.Datastore {
ds := testdatastore.RunPostgresForTestingWithCommitTimestamps(t, "", migrate.Head, false, pgVersion).NewDatastore(t, func(engine, uri string) datastore.Datastore {
ds, err := newPostgresDatastore(uri,
RevisionQuantization(0),
GCWindow(time.Millisecond*1),
Expand Down Expand Up @@ -1306,10 +1328,10 @@ func datastoreWithInterceptorAndTestData(t *testing.T, interceptor pgcommon.Quer
return ds
}

func GCQueriesServedByExpectedIndexes(t *testing.T, _ testdatastore.RunningEngineForTest) {
func GCQueriesServedByExpectedIndexes(t *testing.T, _ testdatastore.RunningEngineForTest, pgVersion string) {
require := require.New(t)
interceptor := &withQueryInterceptor{explanations: make(map[string]string, 0)}
ds := datastoreWithInterceptorAndTestData(t, interceptor)
ds := datastoreWithInterceptorAndTestData(t, interceptor, pgVersion)

// Get the head revision.
ctx := context.Background()
Expand Down
3 changes: 2 additions & 1 deletion internal/testserver/datastore/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/stretchr/testify/require"

"github.com/authzed/spicedb/internal/datastore/postgres/version"
"github.com/authzed/spicedb/pkg/datastore"
"github.com/authzed/spicedb/pkg/migrate"
)
Expand Down Expand Up @@ -62,7 +63,7 @@ func RunDatastoreEngineWithBridge(t testing.TB, engine string, bridgeNetworkName
case "cockroachdb":
return RunCRDBForTesting(t, bridgeNetworkName)
case "postgres":
return RunPostgresForTesting(t, bridgeNetworkName, migrate.Head)
return RunPostgresForTesting(t, bridgeNetworkName, migrate.Head, version.MinimumSupportedPostgresVersion)
case "mysql":
return RunMySQLForTesting(t, bridgeNetworkName)
case "spanner":
Expand Down
9 changes: 4 additions & 5 deletions internal/testserver/datastore/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/stretchr/testify/require"

pgmigrations "github.com/authzed/spicedb/internal/datastore/postgres/migrations"
pgversion "github.com/authzed/spicedb/internal/datastore/postgres/version"
"github.com/authzed/spicedb/pkg/datastore"
"github.com/authzed/spicedb/pkg/migrate"
"github.com/authzed/spicedb/pkg/secrets"
Expand All @@ -29,11 +28,11 @@ type postgresTester struct {
}

// RunPostgresForTesting returns a RunningEngineForTest for postgres
func RunPostgresForTesting(t testing.TB, bridgeNetworkName string, targetMigration string) RunningEngineForTest {
return RunPostgresForTestingWithCommitTimestamps(t, bridgeNetworkName, targetMigration, true)
func RunPostgresForTesting(t testing.TB, bridgeNetworkName string, targetMigration string, pgVersion string) RunningEngineForTest {
return RunPostgresForTestingWithCommitTimestamps(t, bridgeNetworkName, targetMigration, true, pgVersion)
}

func RunPostgresForTestingWithCommitTimestamps(t testing.TB, bridgeNetworkName string, targetMigration string, withCommitTimestamps bool) RunningEngineForTest {
func RunPostgresForTestingWithCommitTimestamps(t testing.TB, bridgeNetworkName string, targetMigration string, withCommitTimestamps bool, pgVersion string) RunningEngineForTest {
pool, err := dockertest.NewPool("")
require.NoError(t, err)

Expand All @@ -47,7 +46,7 @@ func RunPostgresForTestingWithCommitTimestamps(t testing.TB, bridgeNetworkName s
resource, err := pool.RunWithOptions(&dockertest.RunOptions{
Name: name,
Repository: "postgres",
Tag: pgversion.MinimumSupportedPostgresVersion,
Tag: pgVersion,
Env: []string{"POSTGRES_PASSWORD=secret", "POSTGRES_DB=defaultdb"},
ExposedPorts: []string{"5432/tcp"},
NetworkID: bridgeNetworkName,
Expand Down
Loading