diff --git a/pkg/transformers/bite/repository.go b/pkg/transformers/bite/repository.go index f5417d54..231cf8e6 100644 --- a/pkg/transformers/bite/repository.go +++ b/pkg/transformers/bite/repository.go @@ -18,6 +18,8 @@ import ( "fmt" "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants" ) type BiteRepository struct { @@ -49,10 +51,7 @@ func (repository BiteRepository) Create(headerID int64, models []interface{}) er return err } } - _, err = tx.Exec(`INSERT INTO public.checked_headers (header_id, bite_checked) - VALUES ($1, $2) - ON CONFLICT (header_id) DO - UPDATE SET bite_checked = $2`, headerID, true) + err = shared.MarkHeaderCheckedInTransaction(headerID, tx, constants.BiteChecked) if err != nil { tx.Rollback() return err @@ -62,26 +61,9 @@ func (repository BiteRepository) Create(headerID int64, models []interface{}) er } func (repository BiteRepository) MarkHeaderChecked(headerID int64) error { - _, err := repository.db.Exec(`INSERT INTO public.checked_headers (header_id, bite_checked) - VALUES ($1, $2) - ON CONFLICT (header_id) DO - UPDATE SET bite_checked = $2`, headerID, true) - return err + return shared.MarkHeaderChecked(headerID, repository.db, constants.BiteChecked) } func (repository BiteRepository) MissingHeaders(startingBlockNumber int64, endingBlockNumber int64) ([]core.Header, error) { - var result []core.Header - err := repository.db.Select( - &result, - `SELECT headers.id, headers.block_number FROM headers - LEFT JOIN checked_headers on headers.id = header_id - WHERE (header_id ISNULL OR bite_checked IS FALSE) - AND headers.block_number >= $1 - AND headers.block_number <= $2 - AND headers.eth_node_fingerprint = $3`, - startingBlockNumber, - endingBlockNumber, - repository.db.Node.ID, - ) - return result, err + return shared.MissingHeaders(startingBlockNumber, endingBlockNumber, repository.db, constants.BiteChecked) } diff --git a/pkg/transformers/bite/repository_test.go b/pkg/transformers/bite/repository_test.go index eb899f0a..480fe165 100644 --- a/pkg/transformers/bite/repository_test.go +++ b/pkg/transformers/bite/repository_test.go @@ -15,48 +15,50 @@ package bite_test import ( - "database/sql" - "math/rand" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/vulcanize/vulcanizedb/pkg/core" - "github.com/vulcanize/vulcanizedb/pkg/datastore" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories" "github.com/vulcanize/vulcanizedb/pkg/fakes" "github.com/vulcanize/vulcanizedb/pkg/transformers/bite" - "github.com/vulcanize/vulcanizedb/pkg/transformers/factories" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants" "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data" + "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/shared_behaviors" "github.com/vulcanize/vulcanizedb/test_config" ) var _ = Describe("Bite repository", func() { var ( - biteRepository factories.Repository - db *postgres.DB - err error - headerRepository datastore.HeaderRepository + biteRepository bite.BiteRepository + db *postgres.DB ) BeforeEach(func() { db = test_config.NewTestDB(test_config.NewTestNode()) test_config.CleanTestDB(db) - headerRepository = repositories.NewHeaderRepository(db) - biteRepository = &bite.BiteRepository{} + biteRepository = bite.BiteRepository{} biteRepository.SetDB(db) }) Describe("Create", func() { - var headerID int64 + modelWithDifferentLogIdx := test_data.BiteModel + modelWithDifferentLogIdx.LogIndex++ + inputs := shared_behaviors.CreateBehaviorInputs{ + CheckedHeaderColumnName: constants.BiteChecked, + LogEventTableName: "maker.bite", + TestModel: test_data.BiteModel, + ModelWithDifferentLogIdx: modelWithDifferentLogIdx, + Repository: &biteRepository, + } - BeforeEach(func() { - headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader) - Expect(err).NotTo(HaveOccurred()) - }) + shared_behaviors.SharedRepositoryCreateBehaviors(&inputs) It("persists a bite record", func() { + headerRepository := repositories.NewHeaderRepository(db) + headerID, err := headerRepository.CreateOrUpdateHeader(fakes.FakeHeader) + Expect(err).NotTo(HaveOccurred()) + err = biteRepository.Create(headerID, []interface{}{test_data.BiteModel}) Expect(err).NotTo(HaveOccurred()) @@ -74,156 +76,24 @@ var _ = Describe("Bite repository", func() { Expect(dbBite.TransactionIndex).To(Equal(test_data.BiteModel.TransactionIndex)) Expect(dbBite.Raw).To(MatchJSON(test_data.BiteModel.Raw)) }) - - It("marks header as checked for logs", func() { - err = biteRepository.Create(headerID, []interface{}{test_data.BiteModel}) - - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT bite_checked FROM public.checked_headers WHERE header_id = $1`, headerID) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("updates a header as checked if row already exists", func() { - _, err = db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerID) - Expect(err).NotTo(HaveOccurred()) - err = biteRepository.Create(headerID, []interface{}{test_data.BiteModel}) - - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT bite_checked FROM public.checked_headers WHERE header_id = $1`, headerID) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("does not duplicate bite events", func() { - err = biteRepository.Create(headerID, []interface{}{test_data.BiteModel}) - Expect(err).NotTo(HaveOccurred()) - - err = biteRepository.Create(headerID, []interface{}{test_data.BiteModel}) - - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint")) - }) - - It("removes bite if corresponding header is deleted", func() { - err = biteRepository.Create(headerID, []interface{}{test_data.BiteModel}) - Expect(err).NotTo(HaveOccurred()) - - _, err = db.Exec(`DELETE FROM headers WHERE id = $1`, headerID) - - Expect(err).NotTo(HaveOccurred()) - var dbBite bite.BiteModel - err = db.Get(&dbBite, `SELECT ilk, urn, ink, art, tab, nflip, iart, log_idx, tx_idx, raw_log FROM maker.bite WHERE header_id = $1`, headerID) - Expect(err).To(HaveOccurred()) - Expect(err).To(MatchError(sql.ErrNoRows)) - }) - - It("returns an error if the model type is not a Bite", func() { - err = biteRepository.Create(headerID, []interface{}{test_data.WrongModel{}}) - - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("model of type test_data.WrongModel, not bite.BiteModel")) - }) }) Describe("MarkHeaderChecked", func() { - var headerID int64 + inputs := shared_behaviors.MarkedHeaderCheckedBehaviorInputs{ + CheckedHeaderColumnName: constants.BiteChecked, + Repository: &biteRepository, + } - BeforeEach(func() { - headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader) - Expect(err).NotTo(HaveOccurred()) - }) - - It("creates a row for a new headerID", func() { - err = biteRepository.MarkHeaderChecked(headerID) - - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT bite_checked FROM public.checked_headers WHERE header_id = $1`, headerID) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("updates row when headerID already exists", func() { - _, err = db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerID) - - err = biteRepository.MarkHeaderChecked(headerID) - - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT bite_checked FROM public.checked_headers WHERE header_id = $1`, headerID) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) + shared_behaviors.SharedRepositoryMarkHeaderCheckedBehaviors(&inputs) }) Describe("MissingHeaders", func() { - var ( - startingBlock, endingBlock, biteBlock int64 - blockNumbers, headerIDs []int64 - ) - BeforeEach(func() { - startingBlock = rand.Int63() - biteBlock = startingBlock + 1 - endingBlock = startingBlock + 2 + inputs := shared_behaviors.MissingHeadersBehaviorInputs{ + Repository: &biteRepository, + RepositoryTwo: &bite.BiteRepository{}, + } - blockNumbers = []int64{startingBlock, biteBlock, endingBlock, endingBlock + 1} - - headerIDs = []int64{} - for _, n := range blockNumbers { - headerID, err := headerRepository.CreateOrUpdateHeader(fakes.GetFakeHeader(n)) - Expect(err).NotTo(HaveOccurred()) - headerIDs = append(headerIDs, headerID) - } - }) - - It("returns headers that haven't been checked", func() { - err := biteRepository.MarkHeaderChecked(headerIDs[1]) - Expect(err).NotTo(HaveOccurred()) - - headers, err := biteRepository.MissingHeaders(startingBlock, endingBlock) - - Expect(err).NotTo(HaveOccurred()) - Expect(len(headers)).To(Equal(2)) - Expect(headers[0].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock))) - Expect(headers[1].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock))) - }) - - It("only treats headers as checked if bite logs have been checked", func() { - _, err := db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerIDs[1]) - Expect(err).NotTo(HaveOccurred()) - - headers, err := biteRepository.MissingHeaders(startingBlock, endingBlock) - - Expect(err).NotTo(HaveOccurred()) - Expect(len(headers)).To(Equal(3)) - Expect(headers[0].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock), Equal(biteBlock))) - Expect(headers[1].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock), Equal(biteBlock))) - Expect(headers[2].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock), Equal(biteBlock))) - }) - - It("only returns headers associated with the current node", func() { - err := biteRepository.MarkHeaderChecked(headerIDs[0]) - Expect(err).NotTo(HaveOccurred()) - dbTwo := test_config.NewTestDB(core.Node{ID: "second"}) - headerRepositoryTwo := repositories.NewHeaderRepository(dbTwo) - for _, n := range blockNumbers { - _, err = headerRepositoryTwo.CreateOrUpdateHeader(fakes.GetFakeHeader(n)) - Expect(err).NotTo(HaveOccurred()) - } - biteRepositoryTwo := bite.BiteRepository{} - biteRepositoryTwo.SetDB(dbTwo) - - nodeOneMissingHeaders, err := biteRepository.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1]) - Expect(err).NotTo(HaveOccurred()) - Expect(len(nodeOneMissingHeaders)).To(Equal(len(blockNumbers) - 1)) - - nodeTwoMissingHeaders, err := biteRepositoryTwo.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1]) - Expect(err).NotTo(HaveOccurred()) - Expect(len(nodeTwoMissingHeaders)).To(Equal(len(blockNumbers))) - }) + shared_behaviors.SharedRepositoryMissingHeadersBehaviors(&inputs) }) }) diff --git a/pkg/transformers/flip_kick/repository.go b/pkg/transformers/flip_kick/repository.go index 5e03f48e..4c11f060 100644 --- a/pkg/transformers/flip_kick/repository.go +++ b/pkg/transformers/flip_kick/repository.go @@ -19,6 +19,8 @@ import ( "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants" ) type FlipKickRepository struct { @@ -45,10 +47,7 @@ func (fkr FlipKickRepository) Create(headerId int64, models []interface{}) error return err } } - _, err = tx.Exec(`INSERT INTO public.checked_headers (header_id, flip_kick_checked) - VALUES ($1, $2) - ON CONFLICT (header_id) DO - UPDATE SET flip_kick_checked = $2`, headerId, true) + err = shared.MarkHeaderCheckedInTransaction(headerId, tx, constants.FlipKickChecked) if err != nil { tx.Rollback() return err @@ -57,34 +56,11 @@ func (fkr FlipKickRepository) Create(headerId int64, models []interface{}) error } func (fkr FlipKickRepository) MarkHeaderChecked(headerId int64) error { - _, err := fkr.db.Exec(`INSERT INTO public.checked_headers (header_id, flip_kick_checked) - VALUES ($1, $2) - ON CONFLICT (header_id) DO - UPDATE SET flip_kick_checked = $2`, headerId, true) - return err + return shared.MarkHeaderChecked(headerId, fkr.db, constants.FlipKickChecked) } func (fkr FlipKickRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) { - var result []core.Header - err := fkr.db.Select( - &result, - `SELECT headers.id, headers.block_number FROM headers - LEFT JOIN checked_headers on headers.id = header_id - WHERE (header_id ISNULL OR flip_kick_checked IS FALSE) - AND headers.block_number >= $1 - AND headers.block_number <= $2 - AND headers.eth_node_fingerprint = $3`, - startingBlockNumber, - endingBlockNumber, - fkr.db.Node.ID, - ) - - if err != nil { - fmt.Println("Error:", err) - return result, err - } - - return result, nil + return shared.MissingHeaders(startingBlockNumber, endingBlockNumber, fkr.db, constants.FlipKickChecked) } func (fkr *FlipKickRepository) SetDB(db *postgres.DB) { diff --git a/pkg/transformers/flip_kick/repository_test.go b/pkg/transformers/flip_kick/repository_test.go index 509f1a0a..7ecb5cb0 100644 --- a/pkg/transformers/flip_kick/repository_test.go +++ b/pkg/transformers/flip_kick/repository_test.go @@ -18,42 +18,46 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories" "github.com/vulcanize/vulcanizedb/pkg/fakes" "github.com/vulcanize/vulcanizedb/pkg/transformers/flip_kick" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants" "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data" + "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/shared_behaviors" "github.com/vulcanize/vulcanizedb/test_config" ) var _ = Describe("FlipKick Repository", func() { var db *postgres.DB var flipKickRepository flip_kick.FlipKickRepository - var headerId int64 - var blockNumber int64 - var flipKick = test_data.FlipKickModel BeforeEach(func() { db = test_config.NewTestDB(test_config.NewTestNode()) test_config.CleanTestDB(db) flipKickRepository = flip_kick.FlipKickRepository{} flipKickRepository.SetDB(db) - blockNumber = GinkgoRandomSeed() - headerId = createHeader(db, blockNumber) - - _, err := db.Exec(`DELETE from maker.flip_kick;`) - Expect(err).NotTo(HaveOccurred()) }) Describe("Create", func() { - AfterEach(func() { - _, err := db.Exec(`DELETE from headers`) - Expect(err).NotTo(HaveOccurred()) - }) + modelWithDifferentLogIdx := test_data.FlipKickModel + modelWithDifferentLogIdx.LogIndex++ + inputs := shared_behaviors.CreateBehaviorInputs{ + CheckedHeaderColumnName: constants.FlipKickChecked, + LogEventTableName: "maker.flip_kick", + TestModel: test_data.FlipKickModel, + ModelWithDifferentLogIdx: modelWithDifferentLogIdx, + Repository: &flipKickRepository, + } + + shared_behaviors.SharedRepositoryCreateBehaviors(&inputs) It("persists flip_kick records", func() { - err := flipKickRepository.Create(headerId, []interface{}{flipKick}) + headerRepository := repositories.NewHeaderRepository(db) + headerId, err := headerRepository.CreateOrUpdateHeader(fakes.FakeHeader) + Expect(err).NotTo(HaveOccurred()) + + err = flipKickRepository.Create(headerId, []interface{}{test_data.FlipKickModel}) Expect(err).NotTo(HaveOccurred()) assertDBRecordCount(db, "maker.flip_kick", 1) @@ -62,150 +66,35 @@ var _ = Describe("FlipKick Repository", func() { err = db.QueryRowx(`SELECT * FROM maker.flip_kick`).StructScan(&dbResult) Expect(err).NotTo(HaveOccurred()) Expect(dbResult.HeaderId).To(Equal(headerId)) - Expect(dbResult.BidId).To(Equal(flipKick.BidId)) - Expect(dbResult.Lot).To(Equal(flipKick.Lot)) - Expect(dbResult.Bid).To(Equal(flipKick.Bid)) - Expect(dbResult.Gal).To(Equal(flipKick.Gal)) - Expect(dbResult.End.Equal(flipKick.End)).To(BeTrue()) - Expect(dbResult.Urn).To(Equal(flipKick.Urn)) - Expect(dbResult.Tab).To(Equal(flipKick.Tab)) - Expect(dbResult.TransactionIndex).To(Equal(flipKick.TransactionIndex)) - Expect(dbResult.LogIndex).To(Equal(flipKick.LogIndex)) - Expect(dbResult.Raw).To(MatchJSON(flipKick.Raw)) - }) - - It("marks header checked", func() { - err := flipKickRepository.Create(headerId, []interface{}{flipKick}) - Expect(err).NotTo(HaveOccurred()) - - var headerChecked bool - err = db.Get(&headerChecked, `SELECT flip_kick_checked FROM public.checked_headers WHERE header_id = $1`, headerId) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("updates the header to checked if checked headers row already exists", func() { - _, err := db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerId) - Expect(err).NotTo(HaveOccurred()) - err = flipKickRepository.Create(headerId, []interface{}{flipKick}) - Expect(err).NotTo(HaveOccurred()) - - var headerChecked bool - err = db.Get(&headerChecked, `SELECT flip_kick_checked FROM public.checked_headers WHERE header_id = $1`, headerId) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("returns an error if inserting the flip_kick record fails", func() { - err := flipKickRepository.Create(headerId, []interface{}{flipKick}) - Expect(err).NotTo(HaveOccurred()) - - err = flipKickRepository.Create(headerId, []interface{}{flipKick}) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint")) - }) - - It("allows for multiple flip kick events in one transaction if they have different log indexes", func() { - newFlipKick := test_data.FlipKickModel - newFlipKick.LogIndex = newFlipKick.LogIndex + 1 - err := flipKickRepository.Create(headerId, []interface{}{newFlipKick}) - - Expect(err).NotTo(HaveOccurred()) - }) - - It("deletes the flip_kick records if its corresponding header record is deleted", func() { - err := flipKickRepository.Create(headerId, []interface{}{flipKick}) - Expect(err).NotTo(HaveOccurred()) - assertDBRecordCount(db, "maker.flip_kick", 1) - assertDBRecordCount(db, "headers", 1) - - _, err = db.Exec(`DELETE FROM headers where id = $1`, headerId) - Expect(err).NotTo(HaveOccurred()) - - assertDBRecordCount(db, "headers", 0) - assertDBRecordCount(db, "maker.flip_kick", 0) - }) - - It("returns an error if the wrong model type is passed in", func() { - err := flipKickRepository.Create(headerId, []interface{}{test_data.WrongModel{}}) - - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("model of type")) + Expect(dbResult.BidId).To(Equal(test_data.FlipKickModel.BidId)) + Expect(dbResult.Lot).To(Equal(test_data.FlipKickModel.Lot)) + Expect(dbResult.Bid).To(Equal(test_data.FlipKickModel.Bid)) + Expect(dbResult.Gal).To(Equal(test_data.FlipKickModel.Gal)) + Expect(dbResult.End.Equal(test_data.FlipKickModel.End)).To(BeTrue()) + Expect(dbResult.Urn).To(Equal(test_data.FlipKickModel.Urn)) + Expect(dbResult.Tab).To(Equal(test_data.FlipKickModel.Tab)) + Expect(dbResult.TransactionIndex).To(Equal(test_data.FlipKickModel.TransactionIndex)) + Expect(dbResult.LogIndex).To(Equal(test_data.FlipKickModel.LogIndex)) + Expect(dbResult.Raw).To(MatchJSON(test_data.FlipKickModel.Raw)) }) }) Describe("MarkHeaderChecked", func() { - It("creates a row for a new headerID", func() { - err := flipKickRepository.MarkHeaderChecked(headerId) + inputs := shared_behaviors.MarkedHeaderCheckedBehaviorInputs{ + CheckedHeaderColumnName: constants.FlipKickChecked, + Repository: &flipKickRepository, + } - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT flip_kick_checked FROM public.checked_headers WHERE header_id = $1`, headerId) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("updates row when headerID already exists", func() { - _, err := db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerId) - Expect(err).NotTo(HaveOccurred()) - - err = flipKickRepository.MarkHeaderChecked(headerId) - - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT flip_kick_checked FROM public.checked_headers WHERE header_id = $1`, headerId) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) + shared_behaviors.SharedRepositoryMarkHeaderCheckedBehaviors(&inputs) }) - Describe("When there are multiple nodes", func() { - var db2 *postgres.DB - var flipKickRepository2 flip_kick.FlipKickRepository + Describe("missing headers", func() { + inputs := shared_behaviors.MissingHeadersBehaviorInputs{ + Repository: &flipKickRepository, + RepositoryTwo: &flip_kick.FlipKickRepository{}, + } - BeforeEach(func() { - //create database for the second node - node2 := core.Node{ - GenesisBlock: "GENESIS", - NetworkID: 1, - ID: "node2", - ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9", - } - db2 = test_config.NewTestDB(node2) - flipKickRepository2 = flip_kick.FlipKickRepository{} - flipKickRepository2.SetDB(db2) - createHeader(db2, blockNumber) - - _, err := db2.Exec(`DELETE from maker.flip_kick;`) - Expect(err).NotTo(HaveOccurred()) - }) - - It("only includes missing headers for the current node", func() { - node1missingHeaders, err := flipKickRepository.MissingHeaders(blockNumber, blockNumber) - Expect(err).NotTo(HaveOccurred()) - Expect(len(node1missingHeaders)).To(Equal(1)) - - node2MissingHeaders, err := flipKickRepository2.MissingHeaders(blockNumber, blockNumber) - Expect(err).NotTo(HaveOccurred()) - Expect(len(node2MissingHeaders)).To(Equal(1)) - }) - }) - - Describe("MissingHeaders", func() { - It("returns headers that haven't been marked as checked", func() { - startingBlock := blockNumber - 3 - endingBlock := blockNumber + 3 - err := flipKickRepository.MarkHeaderChecked(headerId) - Expect(err).NotTo(HaveOccurred()) - - newBlockNumber := blockNumber + 3 - newHeaderId := createHeader(db, newBlockNumber) - createHeader(db, blockNumber+10) //this one is out of the block range and shouldn't be included - headers, err := flipKickRepository.MissingHeaders(startingBlock, endingBlock) - Expect(len(headers)).To(Equal(1)) - Expect(headers[0].Id).To(Equal(newHeaderId)) - Expect(headers[0].BlockNumber).To(Equal(newBlockNumber)) - }) + shared_behaviors.SharedRepositoryMissingHeadersBehaviors(&inputs) }) }) @@ -216,14 +105,3 @@ func assertDBRecordCount(db *postgres.DB, dbTable string, expectedCount int) { Expect(err).NotTo(HaveOccurred()) Expect(count).To(Equal(expectedCount)) } - -func createHeader(db *postgres.DB, blockNumber int64) (headerId int64) { - headerRepository := repositories.NewHeaderRepository(db) - _, err := headerRepository.CreateOrUpdateHeader(fakes.GetFakeHeader(blockNumber)) - Expect(err).NotTo(HaveOccurred()) - - var dbHeader core.Header - err = db.Get(&dbHeader, `SELECT id, block_number, hash, raw FROM public.headers WHERE block_number = $1 AND eth_node_id = $2`, blockNumber, db.NodeID) - Expect(err).NotTo(HaveOccurred()) - return dbHeader.Id -} diff --git a/pkg/transformers/flop_kick/repository.go b/pkg/transformers/flop_kick/repository.go index bfa14560..467d58ad 100644 --- a/pkg/transformers/flop_kick/repository.go +++ b/pkg/transformers/flop_kick/repository.go @@ -18,14 +18,16 @@ import ( "fmt" "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants" ) type FlopKickRepository struct { db *postgres.DB } -func (r FlopKickRepository) Create(headerId int64, models []interface{}) error { - tx, err := r.db.Begin() +func (repository FlopKickRepository) Create(headerId int64, models []interface{}) error { + tx, err := repository.db.Begin() if err != nil { return err } @@ -46,10 +48,7 @@ func (r FlopKickRepository) Create(headerId int64, models []interface{}) error { } } - _, err = tx.Exec(`INSERT INTO public.checked_headers (header_id, flop_kick_checked) - VALUES ($1, $2) - ON CONFLICT (header_id) DO - UPDATE SET flop_kick_checked = $2`, headerId, true) + err = shared.MarkHeaderCheckedInTransaction(headerId, tx, constants.FlopKickChecked) if err != nil { tx.Rollback() return err @@ -58,30 +57,12 @@ func (r FlopKickRepository) Create(headerId int64, models []interface{}) error { return tx.Commit() } -func (r FlopKickRepository) MarkHeaderChecked(headerId int64) error { - _, err := r.db.Exec(`INSERT INTO public.checked_headers (header_id, flop_kick_checked) - VALUES ($1, $2) - ON CONFLICT (header_id) DO - UPDATE SET flop_kick_checked = $2`, headerId, true) - return err +func (repository FlopKickRepository) MarkHeaderChecked(headerId int64) error { + return shared.MarkHeaderChecked(headerId, repository.db, constants.FlopKickChecked) } -func (r FlopKickRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) { - var result []core.Header - err := r.db.Select( - &result, - `SELECT headers.id, headers.block_number FROM headers - LEFT JOIN checked_headers on headers.id = header_id - WHERE (header_id ISNULL OR flop_kick_checked IS FALSE) - AND headers.block_number >= $1 - AND headers.block_number <= $2 - AND headers.eth_node_fingerprint = $3`, - startingBlockNumber, - endingBlockNumber, - r.db.Node.ID, - ) - - return result, err +func (repository FlopKickRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) { + return shared.MissingHeaders(startingBlockNumber, endingBlockNumber, repository.db, constants.FlopKickChecked) } func (repository *FlopKickRepository) SetDB(db *postgres.DB) { diff --git a/pkg/transformers/flop_kick/repository_test.go b/pkg/transformers/flop_kick/repository_test.go index 9289a115..c916169d 100644 --- a/pkg/transformers/flop_kick/repository_test.go +++ b/pkg/transformers/flop_kick/repository_test.go @@ -18,22 +18,20 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories" "github.com/vulcanize/vulcanizedb/pkg/fakes" "github.com/vulcanize/vulcanizedb/pkg/transformers/flop_kick" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants" "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data" + "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/shared_behaviors" "github.com/vulcanize/vulcanizedb/test_config" ) var _ = Describe("FlopRepository", func() { var ( - db *postgres.DB - repository flop_kick.FlopKickRepository - headerRepository repositories.HeaderRepository - err error - dbResult test_data.FlopKickDBResult + db *postgres.DB + repository flop_kick.FlopKickRepository ) BeforeEach(func() { @@ -41,22 +39,30 @@ var _ = Describe("FlopRepository", func() { test_config.CleanTestDB(db) repository = flop_kick.FlopKickRepository{} repository.SetDB(db) - headerRepository = repositories.NewHeaderRepository(db) - dbResult = test_data.FlopKickDBResult{} }) Describe("Create", func() { - var headerId int64 + modelWithDifferentLogIdx := test_data.FlopKickModel + modelWithDifferentLogIdx.LogIndex++ + inputs := shared_behaviors.CreateBehaviorInputs{ + CheckedHeaderColumnName: constants.FlopKickChecked, + LogEventTableName: "maker.flop_kick", + TestModel: test_data.FlopKickModel, + ModelWithDifferentLogIdx: modelWithDifferentLogIdx, + Repository: &repository, + } - BeforeEach(func() { - headerId, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader) - Expect(err).NotTo(HaveOccurred()) - }) + shared_behaviors.SharedRepositoryCreateBehaviors(&inputs) It("creates FlopKick records", func() { - err := repository.Create(headerId, []interface{}{test_data.FlopKickModel}) + headerRepository := repositories.NewHeaderRepository(db) + headerId, err := headerRepository.CreateOrUpdateHeader(fakes.FakeHeader) Expect(err).NotTo(HaveOccurred()) + err = repository.Create(headerId, []interface{}{test_data.FlopKickModel}) + Expect(err).NotTo(HaveOccurred()) + + dbResult := test_data.FlopKickDBResult{} err = db.QueryRowx(`SELECT * FROM maker.flop_kick WHERE header_id = $1`, headerId).StructScan(&dbResult) Expect(err).NotTo(HaveOccurred()) Expect(dbResult.HeaderId).To(Equal(headerId)) @@ -69,171 +75,23 @@ var _ = Describe("FlopRepository", func() { Expect(dbResult.LogIndex).To(Equal(test_data.FlopKickModel.LogIndex)) Expect(dbResult.Raw).To(MatchJSON(test_data.FlopKickModel.Raw)) }) - - It("marks headerId as checked for flop kick logs", func() { - err := repository.Create(headerId, []interface{}{test_data.FlopKickModel}) - Expect(err).NotTo(HaveOccurred()) - - var headerChecked bool - err = db.Get(&headerChecked, `SELECT flop_kick_checked FROM public.checked_headers WHERE header_id = $1`, headerId) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("updates the header to checked if checked headers row already exists", func() { - _, err := db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerId) - Expect(err).NotTo(HaveOccurred()) - err = repository.Create(headerId, []interface{}{test_data.FlopKickModel}) - Expect(err).NotTo(HaveOccurred()) - - var headerChecked bool - err = db.Get(&headerChecked, `SELECT flop_kick_checked FROM public.checked_headers WHERE header_id = $1`, headerId) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("returns an error if inserting the flop_kick record fails", func() { - err := repository.Create(headerId, []interface{}{test_data.FlopKickModel}) - Expect(err).NotTo(HaveOccurred()) - - err = repository.Create(headerId, []interface{}{test_data.FlopKickModel}) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint")) - }) - - It("allows for multiple flop kick events in one transaction if they have different log indexes", func() { - err := repository.Create(headerId, []interface{}{test_data.FlopKickModel}) - Expect(err).NotTo(HaveOccurred()) - - newFlopKick := test_data.FlopKickModel - newFlopKick.LogIndex = newFlopKick.LogIndex + 1 - err = repository.Create(headerId, []interface{}{newFlopKick}) - - Expect(err).NotTo(HaveOccurred()) - }) - - It("deletes the flop_kick records if its corresponding header record is deleted", func() { - err := repository.Create(headerId, []interface{}{test_data.FlopKickModel}) - Expect(err).NotTo(HaveOccurred()) - - var flopKickCount int - err = db.QueryRow(`SELECT count(*) FROM maker.flop_kick`).Scan(&flopKickCount) - Expect(err).NotTo(HaveOccurred()) - Expect(flopKickCount).To(Equal(1)) - - _, err = db.Exec(`DELETE FROM headers where id = $1`, headerId) - Expect(err).NotTo(HaveOccurred()) - - err = db.QueryRow(`SELECT count(*) FROM maker.flop_kick`).Scan(&flopKickCount) - Expect(err).NotTo(HaveOccurred()) - Expect(flopKickCount).To(Equal(0)) - }) }) Describe("MarkedHeadersChecked", func() { - var headerId int64 + inputs := shared_behaviors.MarkedHeaderCheckedBehaviorInputs{ + CheckedHeaderColumnName: constants.FlopKickChecked, + Repository: &repository, + } - BeforeEach(func() { - headerId, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader) - Expect(err).NotTo(HaveOccurred()) - }) - - It("creates a row for a new headerId", func() { - err := repository.MarkHeaderChecked(headerId) - - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT flop_kick_checked FROM public.checked_headers WHERE header_id = $1`, headerId) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("updates row when headerId already exists", func() { - _, err = db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerId) - err = repository.MarkHeaderChecked(headerId) - - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT flop_kick_checked FROM public.checked_headers WHERE header_id = $1`, headerId) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) + shared_behaviors.SharedRepositoryMarkHeaderCheckedBehaviors(&inputs) }) Describe("MissingHeaders", func() { - var ( - flopKickBlock, startingBlock, endingBlock, outOfRangeBlock int64 - headerIds []int64 - ) + inputs := shared_behaviors.MissingHeadersBehaviorInputs{ + Repository: &repository, + RepositoryTwo: &flop_kick.FlopKickRepository{}, + } - BeforeEach(func() { - flopKickBlock = GinkgoRandomSeed() - startingBlock = flopKickBlock - 1 - endingBlock = flopKickBlock + 1 - outOfRangeBlock = flopKickBlock + 2 - - headerIds = []int64{} - for _, number := range []int64{startingBlock, flopKickBlock, endingBlock, outOfRangeBlock} { - headerId, err := headerRepository.CreateOrUpdateHeader(fakes.GetFakeHeader(number)) - Expect(err).NotTo(HaveOccurred()) - headerIds = append(headerIds, headerId) - } - }) - - It("returns headers haven't been checked", func() { - err = repository.MarkHeaderChecked(headerIds[1]) - Expect(err).NotTo(HaveOccurred()) - - headers, err := repository.MissingHeaders(startingBlock, endingBlock) - - Expect(err).NotTo(HaveOccurred()) - Expect(len(headers)).To(Equal(2)) - Expect(headers[0].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock))) - Expect(headers[1].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock))) - }) - - It("only treats headers as checked if flop_kicks have been checked", func() { - _, err := db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerIds[1]) - Expect(err).NotTo(HaveOccurred()) - - headers, err := repository.MissingHeaders(startingBlock, endingBlock) - - Expect(err).NotTo(HaveOccurred()) - Expect(len(headers)).To(Equal(3)) - Expect(headers[0].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock), Equal(flopKickBlock))) - Expect(headers[1].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock), Equal(flopKickBlock))) - Expect(headers[2].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock), Equal(flopKickBlock))) - }) - - It("only returns missing headers for the current node", func() { - node2 := core.Node{} - db2 := test_config.NewTestDB(node2) - headerRepository2 := repositories.NewHeaderRepository(db2) - flopKickRepository2 := flop_kick.FlopKickRepository{} - flopKickRepository2.SetDB(db2) - - for _, number := range []int64{startingBlock, flopKickBlock, endingBlock} { - headerRepository2.CreateOrUpdateHeader(fakes.GetFakeHeader(number)) - Expect(err).NotTo(HaveOccurred()) - } - - err = repository.MarkHeaderChecked(headerIds[1]) - Expect(err).NotTo(HaveOccurred()) - - node1MissingHeaders, err := repository.MissingHeaders(startingBlock, endingBlock) - Expect(err).NotTo(HaveOccurred()) - Expect(len(node1MissingHeaders)).To(Equal(2)) - - node2MissingHeaders, err := flopKickRepository2.MissingHeaders(startingBlock, endingBlock) - Expect(err).NotTo(HaveOccurred()) - Expect(len(node2MissingHeaders)).To(Equal(3)) - }) - - It("returns an error when wrong model is passed", func() { - err = repository.Create(headerIds[0], []interface{}{test_data.WrongModel{}}) - - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("model of type test_data.WrongModel, not flop_kick.Model")) - }) + shared_behaviors.SharedRepositoryMissingHeadersBehaviors(&inputs) }) }) diff --git a/pkg/transformers/frob/repository.go b/pkg/transformers/frob/repository.go index 9464139d..0aa16ed9 100644 --- a/pkg/transformers/frob/repository.go +++ b/pkg/transformers/frob/repository.go @@ -19,6 +19,8 @@ import ( "github.com/vulcanize/vulcanizedb/pkg/core" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants" ) type FrobRepository struct { @@ -44,10 +46,7 @@ func (repository FrobRepository) Create(headerID int64, models []interface{}) er return err } } - _, err = tx.Exec(`INSERT INTO public.checked_headers (header_id, frob_checked) - VALUES ($1, $2) - ON CONFLICT (header_id) DO - UPDATE SET frob_checked = $2`, headerID, true) + err = shared.MarkHeaderCheckedInTransaction(headerID, tx, constants.FrobChecked) if err != nil { tx.Rollback() return err @@ -56,28 +55,11 @@ func (repository FrobRepository) Create(headerID int64, models []interface{}) er } func (repository FrobRepository) MarkHeaderChecked(headerID int64) error { - _, err := repository.db.Exec(`INSERT INTO public.checked_headers (header_id, frob_checked) - VALUES ($1, $2) - ON CONFLICT (header_id) DO - UPDATE SET frob_checked = $2`, headerID, true) - return err + return shared.MarkHeaderChecked(headerID, repository.db, constants.FrobChecked) } func (repository FrobRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) { - var result []core.Header - err := repository.db.Select( - &result, - `SELECT headers.id, headers.block_number FROM headers - LEFT JOIN checked_headers on headers.id = header_id - WHERE (header_id ISNULL OR frob_checked IS FALSE) - AND headers.block_number >= $1 - AND headers.block_number <= $2 - AND headers.eth_node_fingerprint = $3`, - startingBlockNumber, - endingBlockNumber, - repository.db.Node.ID, - ) - return result, err + return shared.MissingHeaders(startingBlockNumber, endingBlockNumber, repository.db, constants.FrobChecked) } func (repository *FrobRepository) SetDB(db *postgres.DB) { diff --git a/pkg/transformers/frob/repository_test.go b/pkg/transformers/frob/repository_test.go index 470a12c6..5d399edb 100644 --- a/pkg/transformers/frob/repository_test.go +++ b/pkg/transformers/frob/repository_test.go @@ -15,51 +15,55 @@ package frob_test import ( - "database/sql" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "github.com/vulcanize/vulcanizedb/pkg/core" - "github.com/vulcanize/vulcanizedb/pkg/datastore" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres" "github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories" "github.com/vulcanize/vulcanizedb/pkg/fakes" "github.com/vulcanize/vulcanizedb/pkg/transformers/frob" + "github.com/vulcanize/vulcanizedb/pkg/transformers/shared/constants" "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data" + "github.com/vulcanize/vulcanizedb/pkg/transformers/test_data/shared_behaviors" "github.com/vulcanize/vulcanizedb/test_config" ) var _ = Describe("Frob repository", func() { var ( - db *postgres.DB - frobRepository frob.FrobRepository - err error - headerRepository datastore.HeaderRepository + db *postgres.DB + frobRepository frob.FrobRepository ) BeforeEach(func() { - db = test_config.NewTestDB(core.Node{}) + db = test_config.NewTestDB(test_config.NewTestNode()) test_config.CleanTestDB(db) - headerRepository = repositories.NewHeaderRepository(db) frobRepository = frob.FrobRepository{} frobRepository.SetDB(db) }) Describe("Create", func() { - var headerID int64 + modelWithDifferentLogIdx := test_data.FrobModel + modelWithDifferentLogIdx.LogIndex++ + inputs := shared_behaviors.CreateBehaviorInputs{ + CheckedHeaderColumnName: constants.FrobChecked, + LogEventTableName: "maker.frob", + TestModel: test_data.FrobModel, + ModelWithDifferentLogIdx: modelWithDifferentLogIdx, + Repository: &frobRepository, + } - BeforeEach(func() { - headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader) - Expect(err).NotTo(HaveOccurred()) - }) + shared_behaviors.SharedRepositoryCreateBehaviors(&inputs) It("adds a frob", func() { - err = frobRepository.Create(headerID, []interface{}{test_data.FrobModel}) + headerRepository := repositories.NewHeaderRepository(db) + headerID, err := headerRepository.CreateOrUpdateHeader(fakes.FakeHeader) + Expect(err).NotTo(HaveOccurred()) + err = frobRepository.Create(headerID, []interface{}{test_data.FrobModel}) Expect(err).NotTo(HaveOccurred()) var dbFrob frob.FrobModel err = db.Get(&dbFrob, `SELECT art, dart, dink, iart, ilk, ink, urn, log_idx, tx_idx, raw_log FROM maker.frob WHERE header_id = $1`, headerID) + Expect(err).NotTo(HaveOccurred()) Expect(dbFrob.Ilk).To(Equal(test_data.FrobModel.Ilk)) Expect(dbFrob.Urn).To(Equal(test_data.FrobModel.Urn)) @@ -72,156 +76,23 @@ var _ = Describe("Frob repository", func() { Expect(dbFrob.TransactionIndex).To(Equal(test_data.FrobModel.TransactionIndex)) Expect(dbFrob.Raw).To(MatchJSON(test_data.FrobModel.Raw)) }) - - It("marks header as checked for logs", func() { - err = frobRepository.Create(headerID, []interface{}{test_data.FrobModel}) - - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT frob_checked FROM public.checked_headers WHERE header_id = $1`, headerID) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("updates the header to checked if checked headers row already exists", func() { - _, err = db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerID) - Expect(err).NotTo(HaveOccurred()) - - err = frobRepository.Create(headerID, []interface{}{test_data.FrobModel}) - - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT frob_checked FROM public.checked_headers WHERE header_id = $1`, headerID) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("does not duplicate frob events", func() { - err = frobRepository.Create(headerID, []interface{}{test_data.FrobModel}) - Expect(err).NotTo(HaveOccurred()) - - err = frobRepository.Create(headerID, []interface{}{test_data.FrobModel}) - - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint")) - }) - - It("returns an error if the wrong model type is passed in", func() { - err = frobRepository.Create(headerID, []interface{}{test_data.WrongModel{}}) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("model of type test_data.WrongModel, not frob.FrobModel")) - }) - - It("removes frob if corresponding header is deleted", func() { - err = frobRepository.Create(headerID, []interface{}{test_data.FrobModel}) - Expect(err).NotTo(HaveOccurred()) - - _, err = db.Exec(`DELETE FROM headers WHERE id = $1`, headerID) - - Expect(err).NotTo(HaveOccurred()) - var dbFrob frob.FrobModel - err = db.Get(&dbFrob, `SELECT art, iart, ilk, ink, urn, log_idx, tx_idx, raw_log FROM maker.frob WHERE header_id = $1`, headerID) - Expect(err).To(HaveOccurred()) - Expect(err).To(MatchError(sql.ErrNoRows)) - }) }) Describe("MarkHeaderChecked", func() { - var headerID int64 + inputs := shared_behaviors.MarkedHeaderCheckedBehaviorInputs{ + CheckedHeaderColumnName: constants.FrobChecked, + Repository: &frobRepository, + } - BeforeEach(func() { - headerID, err = headerRepository.CreateOrUpdateHeader(fakes.FakeHeader) - Expect(err).NotTo(HaveOccurred()) - }) - - It("creates a row for a new headerID", func() { - err = frobRepository.MarkHeaderChecked(headerID) - - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT frob_checked FROM public.checked_headers WHERE header_id = $1`, headerID) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) - - It("updates row when headerID already exists", func() { - _, err = db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerID) - - err = frobRepository.MarkHeaderChecked(headerID) - - Expect(err).NotTo(HaveOccurred()) - var headerChecked bool - err = db.Get(&headerChecked, `SELECT frob_checked FROM public.checked_headers WHERE header_id = $1`, headerID) - Expect(err).NotTo(HaveOccurred()) - Expect(headerChecked).To(BeTrue()) - }) + shared_behaviors.SharedRepositoryMarkHeaderCheckedBehaviors(&inputs) }) Describe("MissingHeaders", func() { - var ( - startingBlock, endingBlock, frobBlock int64 - blockNumbers, headerIDs []int64 - ) + inputs := shared_behaviors.MissingHeadersBehaviorInputs{ + Repository: &frobRepository, + RepositoryTwo: &frob.FrobRepository{}, + } - BeforeEach(func() { - startingBlock = GinkgoRandomSeed() - frobBlock = startingBlock + 1 - endingBlock = startingBlock + 2 - - blockNumbers = []int64{startingBlock, frobBlock, endingBlock, endingBlock + 1} - - headerIDs = []int64{} - for _, n := range blockNumbers { - headerID, err := headerRepository.CreateOrUpdateHeader(fakes.GetFakeHeader(n)) - Expect(err).NotTo(HaveOccurred()) - headerIDs = append(headerIDs, headerID) - } - }) - - It("returns headers that haven't been checked", func() { - err := frobRepository.MarkHeaderChecked(headerIDs[1]) - Expect(err).NotTo(HaveOccurred()) - - headers, err := frobRepository.MissingHeaders(startingBlock, endingBlock) - - Expect(err).NotTo(HaveOccurred()) - Expect(len(headers)).To(Equal(2)) - Expect(headers[0].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock))) - Expect(headers[1].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock))) - }) - - It("only treats headers as checked if frob logs have been checked", func() { - _, err := db.Exec(`INSERT INTO public.checked_headers (header_id) VALUES ($1)`, headerIDs[1]) - Expect(err).NotTo(HaveOccurred()) - - headers, err := frobRepository.MissingHeaders(startingBlock, endingBlock) - - Expect(err).NotTo(HaveOccurred()) - Expect(len(headers)).To(Equal(3)) - Expect(headers[0].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock), Equal(frobBlock))) - Expect(headers[1].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock), Equal(frobBlock))) - Expect(headers[2].BlockNumber).To(Or(Equal(startingBlock), Equal(endingBlock), Equal(frobBlock))) - }) - - It("only returns headers associated with the current node", func() { - dbTwo := test_config.NewTestDB(core.Node{ID: "second"}) - headerRepositoryTwo := repositories.NewHeaderRepository(dbTwo) - for _, n := range blockNumbers { - _, err = headerRepositoryTwo.CreateOrUpdateHeader(fakes.GetFakeHeader(n)) - Expect(err).NotTo(HaveOccurred()) - } - frobRepositoryTwo := frob.FrobRepository{} - frobRepositoryTwo.SetDB(dbTwo) - err := frobRepository.MarkHeaderChecked(headerIDs[0]) - Expect(err).NotTo(HaveOccurred()) - - nodeOneMissingHeaders, err := frobRepository.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1]) - Expect(err).NotTo(HaveOccurred()) - Expect(len(nodeOneMissingHeaders)).To(Equal(len(blockNumbers) - 1)) - - nodeTwoMissingHeaders, err := frobRepositoryTwo.MissingHeaders(blockNumbers[0], blockNumbers[len(blockNumbers)-1]) - Expect(err).NotTo(HaveOccurred()) - Expect(len(nodeTwoMissingHeaders)).To(Equal(len(blockNumbers))) - }) + shared_behaviors.SharedRepositoryMissingHeadersBehaviors(&inputs) }) }) diff --git a/pkg/transformers/shared/constants/checked_headers.go b/pkg/transformers/shared/constants/checked_headers.go index 39b07214..0e17c648 100644 --- a/pkg/transformers/shared/constants/checked_headers.go +++ b/pkg/transformers/shared/constants/checked_headers.go @@ -1,6 +1,7 @@ package constants var ( + BiteChecked = "bite_checked" CatFileChopLumpChecked = "cat_file_chop_lump_checked" CatFileFlipChecked = "cat_file_flip_checked" CatFilePitVowChecked = "cat_file_pit_vow_checked" @@ -11,6 +12,9 @@ var ( DripFileRepoChecked = "drip_file_repo_checked" DripFileVowChecked = "drip_file_vow_checked" FlapKickChecked = "flap_kick_checked" + FlipKickChecked = "flip_kick_checked" + FlopKickChecked = "flop_kick_checked" + FrobChecked = "frob_checked" PitFileDebtCeilingChecked = "pit_file_debt_ceiling_checked" PitFileIlkChecked = "pit_file_ilk_checked" PitFileStabilityFeeChecked = "pit_file_stability_fee_checked"