From b4121acb1f74da8cd9793a7338254c0c2077b364 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Sat, 5 Apr 2025 19:24:48 +0200 Subject: [PATCH] graph/db: add a framework for testing against SQL backends incrementally In this commit, we implement the postgres and sqlite versions of the NewTestDB function. We add the various build flags so that only one of the three versions of this function can be active at a time. We also introduce the SQLStore struct which is the SQL implementation of the V1Store interface. NOTE: it currently temporarily embeds the KVStore struct so that we can implement the V1Store interface incrementally. For any method not implemented, things will fall back to the KVStore. This is ONLY the case for the time being while this struct is purely used in unit tests only. Once all the methods have been implemented, the KVStore field will be removed from the SQLStore struct. --- .github/workflows/main.yml | 2 ++ graph/db/sql_store.go | 45 ++++++++++++++++++++++++++++++++++++++ graph/db/test_kvdb.go | 2 ++ graph/db/test_postgres.go | 42 +++++++++++++++++++++++++++++++++++ graph/db/test_sqlite.go | 35 +++++++++++++++++++++++++++++ 5 files changed, 126 insertions(+) create mode 100644 graph/db/sql_store.go create mode 100644 graph/db/test_postgres.go create mode 100644 graph/db/test_sqlite.go diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 50ae6ea6d..951637def 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -222,6 +222,8 @@ jobs: - unit tags="kvdb_etcd" - unit tags="kvdb_postgres" - unit tags="kvdb_sqlite" + - unit tags="test_db_sqlite" + - unit tags="test_db_postgres" - unit-race - unit-module diff --git a/graph/db/sql_store.go b/graph/db/sql_store.go new file mode 100644 index 000000000..fa7a49206 --- /dev/null +++ b/graph/db/sql_store.go @@ -0,0 +1,45 @@ +package graphdb + +import ( + "github.com/lightningnetwork/lnd/sqldb" +) + +// SQLQueries is a subset of the sqlc.Querier interface that can be used to +// execute queries against the SQL graph tables. +type SQLQueries interface { +} + +// BatchedSQLQueries is a version of SQLQueries that's capable of batched +// database operations. +type BatchedSQLQueries interface { + SQLQueries + sqldb.BatchedTx[SQLQueries] +} + +// SQLStore is an implementation of the V1Store interface that uses a SQL +// database as the backend. +// +// NOTE: currently, this temporarily embeds the KVStore struct so that we can +// implement the V1Store interface incrementally. For any method not +// implemented, things will fall back to the KVStore. This is ONLY the case +// for the time being while this struct is purely used in unit tests only. +type SQLStore struct { + db BatchedSQLQueries + + // Temporary fall-back to the KVStore so that we can implement the + // interface incrementally. + *KVStore +} + +// A compile-time assertion to ensure that SQLStore implements the V1Store +// interface. +var _ V1Store = (*SQLStore)(nil) + +// NewSQLStore creates a new SQLStore instance given an open BatchedSQLQueries +// storage backend. +func NewSQLStore(db BatchedSQLQueries, kvStore *KVStore) *SQLStore { + return &SQLStore{ + db: db, + KVStore: kvStore, + } +} diff --git a/graph/db/test_kvdb.go b/graph/db/test_kvdb.go index 375712972..0dd3bd2ff 100644 --- a/graph/db/test_kvdb.go +++ b/graph/db/test_kvdb.go @@ -1,3 +1,5 @@ +//go:build !test_db_sqlite && !test_db_postgres + package graphdb import ( diff --git a/graph/db/test_postgres.go b/graph/db/test_postgres.go new file mode 100644 index 000000000..0c2163083 --- /dev/null +++ b/graph/db/test_postgres.go @@ -0,0 +1,42 @@ +//go:build test_db_postgres && !test_db_sqlite + +package graphdb + +import ( + "database/sql" + "testing" + + "github.com/lightningnetwork/lnd/kvdb" + "github.com/lightningnetwork/lnd/sqldb" + "github.com/stretchr/testify/require" +) + +// NewTestDB is a helper function that creates a SQLStore backed by a postgres +// database for testing. At the moment, it embeds a KVStore but once the +// SQLStore fully implements the V1Store interface, the KVStore will be removed. +func NewTestDB(t testing.TB) *SQLStore { + backend, backendCleanup, err := kvdb.GetTestBackend(t.TempDir(), "cgr") + require.NoError(t, err) + + t.Cleanup(backendCleanup) + + graphStore, err := NewKVStore(backend) + require.NoError(t, err) + + pgFixture := sqldb.NewTestPgFixture( + t, sqldb.DefaultPostgresFixtureLifetime, + ) + t.Cleanup(func() { + pgFixture.TearDown(t) + }) + + db := sqldb.NewTestPostgresDB(t, pgFixture).BaseDB + + executor := sqldb.NewTransactionExecutor( + db, func(tx *sql.Tx) SQLQueries { + return db.WithTx(tx) + }, + ) + + return NewSQLStore(executor, graphStore) +} diff --git a/graph/db/test_sqlite.go b/graph/db/test_sqlite.go new file mode 100644 index 000000000..5cfe16812 --- /dev/null +++ b/graph/db/test_sqlite.go @@ -0,0 +1,35 @@ +//go:build !test_db_posgres && test_db_sqlite + +package graphdb + +import ( + "database/sql" + "testing" + + "github.com/lightningnetwork/lnd/kvdb" + "github.com/lightningnetwork/lnd/sqldb" + "github.com/stretchr/testify/require" +) + +// NewTestDB is a helper function that creates a SQLStore backed by a sqlite +// database for testing. At the moment, it embeds a KVStore but once the +// SQLStore fully implements the V1Store interface, the KVStore will be removed. +func NewTestDB(t testing.TB) *SQLStore { + backend, backendCleanup, err := kvdb.GetTestBackend(t.TempDir(), "cgr") + require.NoError(t, err) + + t.Cleanup(backendCleanup) + + graphStore, err := NewKVStore(backend) + require.NoError(t, err) + + db := sqldb.NewTestSqliteDB(t).BaseDB + + executor := sqldb.NewTransactionExecutor( + db, func(tx *sql.Tx) SQLQueries { + return db.WithTx(tx) + }, + ) + + return NewSQLStore(executor, graphStore) +}