func TestDBToEvent(t *testing.T) {
	persister, err := setupTestTable()
	if err != nil {
		t.Error(err)
	}
	defer deleteTestTableForTesting(t, persister)
	eventTestTableName := persister.GetTableName(eventTestTableType)
	appEvent, err := setupApplicationEvent(true)
	if err != nil {
		t.Errorf("setupEvent should have succeeded: err: %v", err)
	}
	events := []*model.Event{appEvent}
	errs := persister.saveEventsToTable(events, eventTestTableName)
	if len(errs) > 0 {
		t.Errorf("Cannot save event to event_test table: %v", errs[0])
	}
	appEventDB, err := allEventsFromTable(persister, eventTestTableName)
	if err != nil {
		t.Errorf("Cannot retrieve events from table: err: %v", err)
	}
	dbEvent := appEventDB[0]
	appEventFromDB, err := dbEvent.DBToEventData()
	if err != nil {
		t.Errorf("Could not convert db event back to civilevent: err: %v", err)
	}
	if appEvent.ContractAddress() != appEventFromDB.ContractAddress() {
		t.Errorf("ContractAddress not equal: %v %v", appEvent.ContractAddress(), appEventFromDB.ContractAddress())
	}
	if appEvent.ContractName() != appEventFromDB.ContractName() {
		t.Errorf("ContractName not equal: %v %v", appEvent.ContractName(), appEventFromDB.ContractName())
	}
	if appEvent.Hash() != appEventFromDB.Hash() {
		t.Errorf("Hash not equal: %v %v", appEvent.Hash(), appEventFromDB.Hash())
	}
	if appEvent.EventType() != appEventFromDB.EventType() {
		t.Errorf("EventType not equal: %v %v", appEvent.EventType(), appEventFromDB.EventType())
	}
	if appEvent.Timestamp() != appEventFromDB.Timestamp() {
		t.Errorf("Timestamp not equal: %v %v", appEvent.Timestamp(), appEventFromDB.Timestamp())
	}
	if !reflect.DeepEqual(appEventFromDB.EventPayload(), appEvent.EventPayload()) {
		t.Errorf("EventPayloads not equal: %v %v", appEvent.EventPayload(), appEventFromDB.EventPayload())
	}
	civilLogPayload := appEvent.LogPayload()
	civilLogFromDBPayload := appEventFromDB.LogPayload()
	if civilLogPayload.Address != civilLogFromDBPayload.Address {
		t.Errorf("Address in Log not equal: %v %v", civilLogPayload.Address, civilLogFromDBPayload.Address)
	}
	if !reflect.DeepEqual(civilLogPayload.Topics, civilLogFromDBPayload.Topics) {
		t.Errorf("Topics in Log not equal: %v %v", civilLogPayload.Topics, civilLogFromDBPayload.Topics)
	}
	if !reflect.DeepEqual(civilLogPayload.Data, civilLogFromDBPayload.Data) {
		t.Errorf("Data in Log not equal: %v %v", civilLogPayload.Data, civilLogFromDBPayload.Data)
	}
	if civilLogPayload.BlockNumber != civilLogFromDBPayload.BlockNumber {
		t.Errorf("BlockNumber in Log not equal: %v %v", civilLogPayload.BlockNumber, civilLogFromDBPayload.BlockNumber)
	}
	if civilLogPayload.TxHash != civilLogFromDBPayload.TxHash {
		t.Errorf("TxHash in Log not equal: %v %v", civilLogPayload.TxHash, civilLogFromDBPayload.TxHash)
	}
	if civilLogPayload.TxIndex != civilLogFromDBPayload.TxIndex {
		t.Errorf("TxIndex in Log not equal: %v %v", civilLogPayload.TxIndex, civilLogFromDBPayload.TxIndex)
	}
	if civilLogPayload.BlockHash != civilLogFromDBPayload.BlockHash {
		t.Errorf("BlockHash in Log not equal: %v %v", civilLogPayload.BlockHash, civilLogFromDBPayload.BlockHash)
	}
	if civilLogPayload.Index != civilLogFromDBPayload.Index {
		t.Errorf("Index in Log not equal: %v %v", civilLogPayload.Index, civilLogFromDBPayload.Index)
	}
	if civilLogPayload.Removed != civilLogFromDBPayload.Removed {
		t.Errorf("Removed in Log not equal: %v %v", civilLogPayload.Removed, civilLogFromDBPayload.Removed)
	}
}
This conversion needs to be here, bc we need the actual event after being saved in DB.
package persistence
import (
	"fmt"
	"math/big"
	"reflect"
	"strings"
	"testing"
	"time"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/joincivil/go-common/pkg/generated/contract"
	cstrings "github.com/joincivil/go-common/pkg/strings"
	ctime "github.com/joincivil/go-common/pkg/time"
	"github.com/joincivil/civil-events-crawler/pkg/model"
	"github.com/joincivil/civil-events-crawler/pkg/persistence/postgres"
	"github.com/joincivil/civil-events-crawler/pkg/testutils"
)
const (
	eventTestTableType   = "event_test"
	versionTestTableName = "version_test"
	postgresPort         = 5432
	postgresDBName       = "civil_crawler"
	postgresUser         = "docker"
	postgresPswd         = "docker"
	postgresHost         = "localhost"
)
var (
	contractAddress      = "0x77e5aaBddb760FBa989A1C4B2CDd4aA8Fa3d311d"
	testAddress          = "0xDFe273082089bB7f70Ee36Eebcde64832FE97E55"
	plcrcontractAddress  = "0x05007652cd356eea1d9b736c3eb469a9defd4034"
	testApplicationEvent = &contract.CivilTCRContractApplication{
		ListingAddress: common.HexToAddress(testAddress),
		Deposit:        big.NewInt(1000),
		AppEndDate:     big.NewInt(1653860896),
		Data:           "DATA",
		Applicant:      common.HexToAddress(testAddress),
		Raw: types.Log{
			Address: common.HexToAddress(testAddress),
			Topics:  []common.Hash{},
			Data:        []byte("\u0000`[�c[�5ipfs://QmStDCuCeS6BfXiDRCkqGPvjRxgku79tzFfAfhUHFEFDhq"),
			BlockNumber: 8888888,
			TxHash:      common.Hash{},
			TxIndex:     2,
			BlockHash:   common.Hash{},
			Index:       2,
			Removed:     false,
		},
	}
	testApplicationWhitelistedEvent = &contract.CivilTCRContractApplicationWhitelisted{
		ListingAddress: common.HexToAddress(testAddress),
		Raw: types.Log{
			Address:     common.HexToAddress(testAddress),
			Topics:      []common.Hash{},
			Data:        []byte{},
			BlockNumber: 8888886,
			TxHash:      common.Hash{},
			TxIndex:     3,
			BlockHash:   common.Hash{},
			Index:       2,
			Removed:     false,
		},
	}
	testChallengeEvent = &contract.CivilTCRContractChallenge{
		ListingAddress: common.HexToAddress(testAddress),
		ChallengeID:    big.NewInt(8),
		Data:           "DATA",
		CommitEndDate:  big.NewInt(1653860896),
		RevealEndDate:  big.NewInt(1653860896),
		Challenger:     common.HexToAddress(testAddress),
		Raw: types.Log{
			Address:     common.HexToAddress(testAddress),
			Topics:      []common.Hash{},
			Data:        []byte("thisisdata1"),
			BlockNumber: 8888887,
			TxHash:      common.Hash{},
			TxIndex:     4,
			BlockHash:   common.Hash{},
			Index:       2,
			Removed:     false,
		},
	}
	testNwsrmNameChangedEvent = &contract.NewsroomContractNameChanged{
		NewName: "test newsroom",
		Raw: types.Log{
			Address:     common.HexToAddress(testAddress),
			Topics:      []common.Hash{},
			Data:        []byte("thisisdata2"),
			BlockNumber: 8888889,
			TxHash:      common.Hash{},
			TxIndex:     4,
			BlockHash:   common.Hash{},
			Index:       2,
			Removed:     false,
		},
	}
	testPLCRPollCreatedEvent = &contract.CivilPLCRVotingContractPollCreated{
		VoteQuorum:    big.NewInt(50),
		CommitEndDate: big.NewInt(1653860890),
		RevealEndDate: big.NewInt(1653860900),
		PollID:        big.NewInt(3),
		Creator:       common.HexToAddress(testAddress),
		Raw: types.Log{
			Address:     common.HexToAddress(testAddress),
			Topics:      []common.Hash{},
			Data:        []byte("thisisdata3"),
			BlockNumber: 8898889,
			TxHash:      common.Hash{},
			TxIndex:     4,
			BlockHash:   common.Hash{},
			Index:       3,
			Removed:     false,
		},
	}
)
func setupApplicationEvent(rand bool) (*model.Event, error) {
	if rand {
		randString, _ := cstrings.RandomHexStr(32)
		testApplicationEvent.Raw.TxHash = common.HexToHash(randString)
	}
	return model.NewEventFromContractEvent("Application", "CivilTCRContract", common.HexToAddress(contractAddress),
		testApplicationEvent, ctime.CurrentEpochSecsInInt64(), model.Filterer)
}
func setupApplicationWhitelistedEvent(rand bool) (*model.Event, error) {
	if rand {
		randString, _ := cstrings.RandomHexStr(32)
		testApplicationWhitelistedEvent.Raw.TxHash = common.HexToHash(randString)
	}
	return model.NewEventFromContractEvent("ApplicationWhitelisted", "CivilTCRContract", common.HexToAddress(contractAddress),
		testApplicationWhitelistedEvent, ctime.CurrentEpochSecsInInt64(), model.Watcher)
}
func setupChallengeEvent(rand bool) (*model.Event, error) {
	if rand {
		randString, _ := cstrings.RandomHexStr(32)
		testChallengeEvent.Raw.TxHash = common.HexToHash(randString)
	}
	return model.NewEventFromContractEvent("Challenge", "CivilTCRContract", common.HexToAddress(contractAddress),
		testChallengeEvent, ctime.CurrentEpochSecsInInt64(), model.Filterer)
}
func setupNewsroomNameChanged(rand bool) (*model.Event, error) {
	if rand {
		randString, _ := cstrings.RandomHexStr(32)
		testNwsrmNameChangedEvent.Raw.TxHash = common.HexToHash(randString)
	}
	return model.NewEventFromContractEvent("NameChanged", "NewsroomContract", common.HexToAddress(contractAddress),
		testNwsrmNameChangedEvent, ctime.CurrentEpochSecsInInt64(), model.Watcher)
}
func setupPLCRVotingContractPollCreated(rand bool) (*model.Event, error) {
	if rand {
		randString, _ := cstrings.RandomHexStr(32)
		testPLCRPollCreatedEvent.Raw.TxHash = common.HexToHash(randString)
	}
	return model.NewEventFromContractEvent("PollCreated", "CivilPLCRVotingContract", common.HexToAddress(plcrcontractAddress),
		testPLCRPollCreatedEvent, ctime.CurrentEpochSecsInInt64(), model.Filterer)
}
func setupApplicationEventWithParams(rand bool, contractAddress string, timestamp int64) (*model.Event, error) {
	if rand {
		randString, _ := cstrings.RandomHexStr(32)
		testApplicationEvent.Raw.TxHash = common.HexToHash(randString)
	}
	return model.NewEventFromContractEvent("Application", "CivilTCRContract", common.HexToAddress(contractAddress),
		testApplicationEvent, timestamp, model.Filterer)
}
func setupEvents(rand bool) ([]*model.Event, error) {
	appEvent, err := setupApplicationEvent(rand)
	if err != nil {
		return nil, fmt.Errorf("Cannot setup Application event: %v", err)
	}
	appWhitelisted, err := setupApplicationWhitelistedEvent(rand)
	if err != nil {
		return nil, fmt.Errorf("Cannot setup ApplicationWhitelisted event: %v", err)
	}
	challenge, err := setupChallengeEvent(rand)
	if err != nil {
		return nil, fmt.Errorf("Cannot setup Challenge event: %v", err)
	}
	nameChanged, err := setupNewsroomNameChanged(rand)
	if err != nil {
		return nil, fmt.Errorf("Cannot setup NameChanged event: %v", err)
	}
	pollCreated, err := setupPLCRVotingContractPollCreated(rand)
	if err != nil {
		return nil, fmt.Errorf("Cannot setup PollCreated event: %v", err)
	}
	return []*model.Event{appEvent, appWhitelisted, challenge, nameChanged, pollCreated}, nil
}
func setupEventsDifferentTimes(rand bool) ([]*model.Event, error) {
	appEvent, err := setupApplicationEvent(rand)
	if err != nil {
		return nil, fmt.Errorf("Cannot setup Application event: %v", err)
	}
	time.Sleep(1 * time.Second)
	appWhitelisted, err := setupApplicationWhitelistedEvent(rand)
	if err != nil {
		return nil, fmt.Errorf("Cannot setup ApplicationWhitelisted event: %v", err)
	}
	time.Sleep(1 * time.Second)
	challenge, err := setupChallengeEvent(rand)
	if err != nil {
		return nil, fmt.Errorf("Cannot setup Challenge event: %v", err)
	}
	time.Sleep(1 * time.Second)
	nameChanged, err := setupNewsroomNameChanged(rand)
	if err != nil {
		return nil, fmt.Errorf("Cannot setup NameChanged event: %v", err)
	}
	time.Sleep(1 * time.Second)
	pollCreated, err := setupPLCRVotingContractPollCreated(rand)
	if err != nil {
		return nil, fmt.Errorf("Cannot setup PollCreated event: %v", err)
	}
	return []*model.Event{appEvent, appWhitelisted, challenge, nameChanged, pollCreated}, nil
}
func changeBlockData(blockNo int, event *model.Event) {
	event.LogPayload().BlockNumber = uint64(blockNo)
}
func setupDBConnection() (*PostgresPersister, error) {
	creds := testutils.GetTestDBCreds()
	postgresPersister, err := NewPostgresPersister(creds.Host, creds.Port, creds.User,
		creds.Password, creds.Dbname, nil, nil, nil)
	return postgresPersister, err
}
func allEventsFromTable(persister *PostgresPersister, tableName string) ([]postgres.Event, error) {
	dbEvent := []postgres.Event{}
	queryString := fmt.Sprintf("SELECT event_type, hash, contract_address, contract_name, timestamp, payload, log_payload "+
		"FROM %s;", tableName)
	err := persister.db.Select(&dbEvent, queryString)
	return dbEvent, err
}
func setupTestTable() (*PostgresPersister, error) {
	persister, err := setupDBConnection()
	if err != nil {
		return persister, fmt.Errorf("Error connecting to DB: %v", err)
	}
	version := "f"
	persister.version = &version
	eventTestTableName := persister.GetTableName(eventTestTableType)
	createTableQuery := postgres.CreateEventTableQuery(eventTestTableName)
	_, err = persister.db.Query(createTableQuery)
	if err != nil {
		return persister, fmt.Errorf("Couldn't create test table %v", err)
	}
	return persister, nil
}
func deleteTestTable(persister *PostgresPersister) error {
	version := "f"
	persister.version = &version
	eventTestTableName := persister.GetTableName(eventTestTableType)
	_, err := persister.db.Query(fmt.Sprintf("DROP TABLE %v;", eventTestTableName))
	if err != nil {
		return err
	}
	return nil
}
func deleteTestTableForTesting(t *testing.T, persister *PostgresPersister) {
	err := deleteTestTable(persister)
	if err != nil {
		t.Errorf("Couldn't delete test table %v", err)
	}
	persister.db.Close()
}
func deleteTestTableForBenchmarks(b *testing.B, persister *PostgresPersister) {
	err := deleteTestTable(persister)
	if err != nil {
		b.Errorf("Couldn't delete test table %v", err)
	}
}
func createTestVersionTable(t *testing.T, persister *PostgresPersister) {
	versionTableQuery := postgres.CreateVersionTableQuery(versionTestTableName)
	_, err := persister.db.Exec(versionTableQuery)
	if err != nil {
		t.Errorf("error %v", err)
	}
}
func deleteTestVersionTable(t *testing.T, persister *PostgresPersister) {
	_, err := persister.db.Query(fmt.Sprintf("DROP TABLE %v;", versionTestTableName))
	if err != nil {
		t.Errorf("error: %v", err)
	}
}
func TestDBConnection(t *testing.T) {
	persister, err := setupDBConnection()
	if err != nil {
		t.Errorf("Error connecting to DB: %v", err)
	}
	var result int
	err = persister.db.QueryRow("SELECT 1;").Scan(&result)
	if err != nil {
		t.Errorf("Error querying DB: %v", err)
	}
	if result != 1 {
		t.Errorf("Wrong result from DB")
	}
}
func TestGetAllVersions(t *testing.T) {
	persister, err := setupDBConnection()
	if err != nil {
		t.Errorf("Error connecting to DB: %v", err)
	}
	versionNo := "123456"
	createTestVersionTable(t, persister)
	err = persister.saveVersionToTable(versionTestTableName, &versionNo)
	if err != nil {
		t.Errorf("Error saving  version: %v", err)
	}
	time.Sleep(1 * time.Second)
	versionNo2 := "1234567"
	createTestVersionTable(t, persister)
	err = persister.saveVersionToTable(versionTestTableName, &versionNo2)
	if err != nil {
		t.Errorf("Error saving  version: %v", err)
	}
	time.Sleep(1 * time.Second)
	versionNo3 := "1234568"
	createTestVersionTable(t, persister)
	err = persister.saveVersionToTable(versionTestTableName, &versionNo3)
	if err != nil {
		t.Errorf("Error saving  version: %v", err)
	}
	v, err := persister.oldVersionsFromTable("crawler", versionTestTableName)
	if err != nil {
		t.Errorf("Error getting old versions %v", v)
	}
	if len(v) != 2 {
		t.Errorf("Should be ")
	}
}
func TestTableSetupNoExistingVersion(t *testing.T) {
	persister, err := setupDBConnection()
	if err != nil {
		t.Errorf("Error connecting to DB: %v", err)
	}
	versionNo := "123456"
	createTestVersionTable(t, persister)
	err = persister.saveVersionToTable(versionTestTableName, &versionNo)
	if err != nil {
		t.Errorf("Error saving  version: %v", err)
	}
	persister.version = &versionNo
	err = persister.CreateEventTable()
	if err != nil {
		t.Errorf("Error creating/checking for tables: %v", err)
	}
	tableName := persister.GetTableName("event")
	if err != nil {
		t.Errorf("Error creating/checking for tables: %v", err)
	}
	var exists bool
	queryString := fmt.Sprintf("SELECT EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = '%v');",
		tableName)
	err = persister.db.QueryRow(queryString).Scan(&exists)
	if err != nil {
		t.Errorf("Couldn't get table")
	}
	if !exists {
		t.Errorf("event table does not exist")
	}
	persister.db.Query(fmt.Sprintf("DROP TABLE %v;", tableName))
	deleteTestVersionTable(t, persister)
}
func TestSaveAndRetrieveFromVersionTable(t *testing.T) {
	persister, err := setupDBConnection()
	if err != nil {
		t.Errorf("Error connecting to DB: %v", err)
	}
	createTestVersionTable(t, persister)
	versionNo := "123456"
	err = persister.saveVersionToTable(versionTestTableName, &versionNo)
	if err != nil {
		t.Errorf("Error saving versionNo to table: %v", err)
	}
	versionFromTable, err := persister.retrieveVersionFromTable(versionTestTableName)
	if err != nil {
		t.Errorf("Error retrieving from table: %v", err)
	}
	if *versionFromTable != versionNo {
		t.Errorf("Version numbers do not match, %v, %v", versionNo, *versionFromTable)
	}
	deleteTestVersionTable(t, persister)
}
func TestTableSetupExistingVersion(t *testing.T) {
	persister, err := setupDBConnection()
	if err != nil {
		t.Errorf("Error connecting to DB: %v", err)
	}
	createTestVersionTable(t, persister)
	defer deleteTestVersionTable(t, persister)
	versionNo := "123456"
	err = persister.saveVersionToTable(versionTestTableName, &versionNo)
	if err != nil {
		t.Errorf("Error saving versionNo to table: %v", err)
	}
	versionNoCopy, err := persister.persisterVersionFromTable(versionTestTableName)
	if err != nil {
		t.Errorf("Error getting version %v", err)
	}
	if *versionNoCopy != versionNo {
		t.Errorf("versions don't match %v, %v", versionNo, *versionNoCopy)
	}
	persister.version = nil
	newVersionNo := "1234567"
	time.Sleep(1 * time.Second)
	err = persister.saveVersionToTable(versionTestTableName, &newVersionNo)
	if err != nil {
		t.Errorf("Error creating/checking for tables: %v", err)
	}
	newVersionNoCopy, err := persister.persisterVersionFromTable(versionTestTableName)
	if err != nil {
		t.Errorf("Error getting version %v", err)
	}
	if *newVersionNoCopy != newVersionNo {
		t.Errorf("versions don't match %v, %v", *newVersionNoCopy, newVersionNo)
	}
	persister.version = nil
	newVersionNo2 := "123456"
	time.Sleep(1 * time.Second)
	err = persister.saveVersionToTable(versionTestTableName, &newVersionNo2)
	if err != nil {
		t.Errorf("Error creating/checking for tables: %v", err)
	}
	newVersionNoCopy2, err := persister.persisterVersionFromTable(versionTestTableName)
	if err != nil {
		t.Errorf("Error getting version %v", err)
	}
	if *newVersionNoCopy2 != newVersionNo2 {
		t.Errorf("versions don't match %v, %v", *newVersionNoCopy2, newVersionNo2)
	}
}
func TestUpdateExistenceForVersionTable(t *testing.T) {
	persister, err := setupDBConnection()
	if err != nil {
		t.Errorf("Error connecting to DB: %v", err)
	}
	createTestVersionTable(t, persister)
	defer deleteTestVersionTable(t, persister)
	versionNo := "123456"
	err = persister.saveVersionToTable(versionTestTableName, &versionNo)
	if err != nil {
		t.Errorf("Error saving versionNo to table: %v", err)
	}
	versionNoCopy, err := persister.persisterVersionFromTable(versionTestTableName)
	if err != nil {
		t.Errorf("Error getting version %v", err)
	}
	if *versionNoCopy != versionNo {
		t.Errorf("versions don't match %v, %v", versionNo, *versionNoCopy)
	}
	persister.version = nil
	newVersionNo := "1234567"
	time.Sleep(1 * time.Second)
	err = persister.saveVersionToTable(versionTestTableName, &newVersionNo)
	if err != nil {
		t.Errorf("Error creating/checking for tables: %v", err)
	}
	newVersionNo2 := "1234568"
	time.Sleep(1 * time.Second)
	err = persister.saveVersionToTable(versionTestTableName, &newVersionNo2)
	if err != nil {
		t.Errorf("Error creating/checking for tables: %v", err)
	}
	newVersionNo3 := "1234569"
	time.Sleep(1 * time.Second)
	err = persister.saveVersionToTable(versionTestTableName, &newVersionNo3)
	if err != nil {
		t.Errorf("Error creating/checking for tables: %v", err)
	}
	newVersionNoCopy, err := persister.persisterVersionFromTable(versionTestTableName)
	if err != nil {
		t.Errorf("Error getting version %v", err)
	}
	if *newVersionNoCopy != newVersionNo3 {
		t.Errorf("versions don't match %v, %v", *newVersionNoCopy, newVersionNo)
	}
	err = persister.UpdateExistenceFalseForVersionTable(versionTestTableName, versionNo, CrawlerServiceName)
	if err != nil {
		t.Errorf("Error updating version in table, err: %v", err)
	}
	v, err := persister.oldVersionsFromTable("crawler", versionTestTableName)
	if err != nil {
		t.Errorf("Error getting old versions %v", v)
	}
	if len(v) != 2 {
		t.Errorf("Should have one version but got %v", len(v))
	}
	err = persister.UpdateExistenceFalseForVersionTable(versionTestTableName, newVersionNo, CrawlerServiceName)
	if err != nil {
		t.Errorf("Error updating version in table, err: %v", err)
	}
	v, err = persister.oldVersionsFromTable("crawler", versionTestTableName)
	if err != nil {
		t.Errorf("Error getting old versions %v", v)
	}
	if len(v) != 1 {
		t.Errorf("Should not have gotten any versions but got %v", len(v))
	}
}
func TestIndexCreationTestTable(t *testing.T) {
	persister, err := setupTestTable()
	if err != nil {
		t.Error(err)
	}
	defer deleteTestTableForTesting(t, persister)
	eventTestTableName := persister.GetTableName(eventTestTableType)
	indexCreationQuery := postgres.CreateEventTableIndices(eventTestTableName)
	_, err = persister.db.Query(indexCreationQuery)
	if err != nil {
		t.Errorf("Error creating indices in test table: %v", err)
	}
	_, err = persister.db.Query(indexCreationQuery)
	if err != nil {
		t.Errorf("Error creating indices in test table: %v", err)
	}
}
func TestDuplicateEvents(t *testing.T) {
	persister, err := setupTestTable()
	if err != nil {
		t.Error(err)
	}
	defer deleteTestTableForTesting(t, persister)
	eventTestTableName := persister.GetTableName(eventTestTableType)
	event1, err := setupApplicationEvent(false)
	if err != nil {
		t.Errorf("Cannot setup Application event: %v", err)
	}
	event2, err := setupApplicationEvent(false)
	if err != nil {
		t.Errorf("Cannot setup Application event: %v", err)
	}
	if event1.Hash() != event2.Hash() {
		t.Errorf("Hashes for events should be equal, but they are %v, %v", event1.Hash(), event2.Hash())
	}
	civilEventsFromContract := []*model.Event{event1, event2}
	errs := persister.saveEventsToTable(civilEventsFromContract, eventTestTableName)
	if len(errs) > 0 {
		if !strings.Contains(errs[0].Error(), "duplicate key value violates unique constraint") {
			t.Errorf("Error for duplicate key value should have been thrown")
		}
	}
}
func TestMultipleQueries(t *testing.T) {
	persister, err := setupTestTable()
	if err != nil {
		t.Error(err)
	}
	defer deleteTestTableForTesting(t, persister)
	eventTestTableName := persister.GetTableName(eventTestTableType)
	var errs []error
	for i := 1; i <= 100; i++ {
		events, err := setupEvents(true)
		if err != nil {
			t.Errorf("Couldn't setup civilEvents from contract %v", err)
		}
		errs = persister.saveEventsToTable(events, eventTestTableName)
		if len(errs) > 0 {
			t.Errorf("Cannot save event to events_test table: %v", errs[0])
		}
		_, err = persister.retrieveEventsFromTable(eventTestTableName, &model.RetrieveEventsCriteria{
			Offset:  0,
			Count:   1,
			Reverse: false,
		})
		if err != nil {
			t.Errorf("Couldn't retrieve events %v", err)
		}
		err = persister.PopulateBlockDataFromDB(eventTestTableType)
		if err != nil {
			t.Errorf("Couldn't populate block data %v", err)
		}
	}
}
func TestSaveEvents(t *testing.T) {
	persister, err := setupTestTable()
	if err != nil {
		t.Error(err)
	}
	defer deleteTestTableForTesting(t, persister)
	eventTestTableName := persister.GetTableName(eventTestTableType)
	events, err := setupEvents(true)
	if err != nil {
		t.Errorf("Couldn't setup civilEvent from contract %v", err)
	}
	errs := persister.saveEventsToTable(events, eventTestTableName)
	if len(errs) > 0 {
		t.Errorf("Cannot save event to events_test table: %v", errs[0])
	}
	civilEventsDB, err := allEventsFromTable(persister, eventTestTableName)
	if err != nil {
		t.Errorf("error querying event from events_test table: %v", err)
	}
	if len(civilEventsDB) != 5 {
		t.Errorf("expected there to be 5 events in table but there are %v events", len(civilEventsDB))
	}
}
func BenchmarkSavingManyEventsToEventTestTable(b *testing.B) {
	persister, err := setupTestTable()
	if err != nil {
		b.Error(err)
	}
	defer deleteTestTableForBenchmarks(b, persister)
	eventTestTableName := persister.GetTableName(eventTestTableType)
	numEvents := 100
	numEventTypes := 5
	civilEventsFromContract := make([]*model.Event, 0)
	for i := 1; i <= numEvents; i++ {
		events, err := setupEvents(true)
		if err != nil {
			b.Errorf("Couldn't setup civilEvent from contract %v", err)
		}
		civilEventsFromContract = append(civilEventsFromContract, events...)
	}
	errs := persister.saveEventsToTable(civilEventsFromContract, eventTestTableName)
	if len(errs) > 0 {
		b.Errorf("Cannot save event to event_test table: %v", errs[0])
	}
	var numRows int
	err = persister.db.QueryRow(`SELECT COUNT(*) FROM
                                        event_test`).Scan(&numRows)
	if err != nil {
		b.Errorf("Error querying count: err: %v", err)
	}
	if numRows != numEvents*numEventTypes {
		b.Errorf("Number of rows in event_test table should be %v but it is %v", numEvents, numRows)
	}
}
func TestPersistenceUpdate(t *testing.T) {
	persister, err := setupDBConnection()
	if err != nil {
		t.Errorf("Error connecting to DB: %v", err)
	}
	events, err := setupEvents(true)
	if err != nil {
		t.Errorf("Couldn't setup civilEvents from contracts %v", err)
	}
	err = persister.UpdateLastBlockData(events)
	if err != nil {
		t.Errorf("Couldn't update last block data: %v", err)
	}
	for _, event := range events {
		if persister.LastBlockNumber(event.EventType(), event.ContractAddress()) != event.LogPayload().BlockNumber {
			t.Error("Blocknumber was not updated correctly in persistence")
		}
		if persister.LastBlockHash(event.EventType(), event.ContractAddress()) != event.LogPayload().BlockHash {
			t.Error("Blockhash was not updated correctly in persistence")
		}
	}
	events2, err := setupEvents(true)
	if err != nil {
		t.Errorf("Couldn't setup civilEvents from contracts %v", err)
	}
	err = persister.UpdateLastBlockData(events)
	if err != nil {
		t.Errorf("Couldn't update last block data: %v", err)
	}
	for _, event := range events2 {
		if persister.LastBlockNumber(event.EventType(), event.ContractAddress()) != event.LogPayload().BlockNumber {
			t.Error("Blocknumber was not updated correctly in persistence")
		}
		if persister.LastBlockHash(event.EventType(), event.ContractAddress()) != event.LogPayload().BlockHash {
			t.Error("Blockhash was not updated correctly in persistence")
		}
	}
}
func TestLatestEventsQuery(t *testing.T) {
	persister, err := setupTestTable()
	if err != nil {
		t.Error(err)
	}
	defer deleteTestTableForTesting(t, persister)
	eventTestTableName := persister.GetTableName(eventTestTableType)
	testEvents, err := setupEvents(true)
	if err != nil {
		t.Errorf("Couldn't setup event %v", err)
	}
	time.Sleep(time.Second)
	testEventsLatest, err := setupEvents(true)
	if err != nil {
		t.Errorf("Couldn't setup event %v", err)
	}
	testEvents = append(testEvents, testEventsLatest...)
	numEvents := len(testEventsLatest)
	errs := persister.saveEventsToTable(testEvents, eventTestTableName)
	if len(errs) > 0 {
		t.Errorf("Cannot save event to event_test table: %v", err)
	}
	dbEvents, err := persister.getLatestEvents(eventTestTableName)
	if err != nil {
		t.Errorf("Error retrieving events: %v", err)
	}
	if len(dbEvents) != numEvents {
		t.Errorf("Query should have only returned %v events but there are %v", numEvents, len(dbEvents))
	}
	for i, event := range testEventsLatest {
		latestTimestamp := event.Timestamp()
		queryTimestamp := dbEvents[i].Timestamp
		if latestTimestamp != queryTimestamp {
			t.Errorf("Query didn't pull the latest event for contract %v and event type %v", event.ContractName(), event.EventType())
		}
	}
}
func TestPopulateBlockDataFromDB(t *testing.T) {
	persister, err := setupTestTable()
	if err != nil {
		t.Error(err)
	}
	defer deleteTestTableForTesting(t, persister)
	eventTestTableName := persister.GetTableName(eventTestTableType)
	numEvents := 3
	civilEventsFromContract := make([]*model.Event, 0)
	blockNo := 8888888
	correctEventToBlockData := make(map[common.Address]map[string]PersisterBlockData)
	for i := 1; i <= numEvents; i++ {
		events, err := setupEvents(true)
		if err != nil {
			t.Errorf("Couldn't setup civilEvent from contract %v", err)
		}
		for _, event := range events {
			changeBlockData(blockNo, event)
			contractAddress := event.ContractAddress()
			eventType := event.EventType()
			blockData := PersisterBlockData{event.LogPayload().BlockNumber, event.LogPayload().BlockHash}
			if correctEventToBlockData[contractAddress] == nil {
				correctEventToBlockData[contractAddress] = make(map[string]PersisterBlockData)
			}
			correctEventToBlockData[contractAddress][eventType] = blockData
		}
		blockNo++
		civilEventsFromContract = append(civilEventsFromContract, events...)
	}
	contractAddress, _ = cstrings.RandomHexStr(42)
	for i := 1; i <= numEvents; i++ {
		events, err := setupEvents(true)
		if err != nil {
			t.Errorf("Couldn't setup civilEvent from contract %v", err)
		}
		for _, event := range events {
			changeBlockData(blockNo, event)
			contractAddress := event.ContractAddress()
			eventType := event.EventType()
			blockData := PersisterBlockData{event.LogPayload().BlockNumber, event.LogPayload().BlockHash}
			if correctEventToBlockData[contractAddress] == nil {
				correctEventToBlockData[contractAddress] = make(map[string]PersisterBlockData)
			}
			correctEventToBlockData[contractAddress][eventType] = blockData
		}
		blockNo++
		civilEventsFromContract = append(civilEventsFromContract, events...)
	}
	errs := persister.saveEventsToTable(civilEventsFromContract, eventTestTableName)
	if len(errs) > 0 {
		t.Errorf("Cannot save event to event_test table: %v", errs[0])
	}
	err = persister.PopulateBlockDataFromDB(eventTestTableType)
	if err != nil {
		t.Errorf("Cannot fill persistence, %v", err)
	}
	if !reflect.DeepEqual(correctEventToBlockData, persister.eventToBlockData) {
		t.Errorf("eventToBlockData was not populated correctly. it should be %v but is %v", correctEventToBlockData,
			persister.eventToBlockData)
	}
}
func TestSameTimestampEvents(t *testing.T) {
	persister, err := setupTestTable()
	if err != nil {
		t.Error(err)
	}
	defer deleteTestTableForTesting(t, persister)
	eventTestTableName := persister.GetTableName(eventTestTableType)
	numEvents := 2
	civilEventsFromContract := make([]*model.Event, numEvents)
	timestamp := ctime.CurrentEpochSecsInInt64()
	contractAddress, _ := cstrings.RandomHexStr(42)
	for i := 0; i < numEvents; i++ {
		event, err := setupApplicationEventWithParams(true, contractAddress, timestamp)
		if err != nil {
			t.Errorf("Couldn't setup civilEvent from contract %v", err)
		}
		civilEventsFromContract[i] = event
	}
	errs := persister.saveEventsToTable(civilEventsFromContract, eventTestTableName)
	if len(errs) > 0 {
		t.Errorf("Cannot save event to event_test table: %v", errs[0])
	}
	err = persister.PopulateBlockDataFromDB(eventTestTableType)
	if err != nil {
		t.Errorf("Cannot fill persistence, %v", err)
	}
	if persister.eventToBlockData[common.HexToAddress(contractAddress)]["Application"].BlockNumber !=
		civilEventsFromContract[0].LogPayload().BlockNumber {
		t.Errorf("Block numbers are not equal: %v, %v", persister.eventToBlockData[common.HexToAddress(contractAddress)]["Application"].BlockNumber,
			civilEventsFromContract[0].LogPayload().BlockNumber)
	}
	civilEventsFromContract2 := make([]*model.Event, numEvents)
	timestamp2 := ctime.CurrentEpochSecsInInt64()
	blockNo := 8888888
	for i := 0; i < numEvents; i++ {
		event, err := setupApplicationEventWithParams(true, contractAddress, timestamp2)
		if err != nil {
			t.Errorf("Couldn't setup civilEvent from contract %v", err)
		}
		blockNo++
		changeBlockData(blockNo, event)
		civilEventsFromContract2[i] = event
	}
	errs = persister.saveEventsToTable(civilEventsFromContract2, eventTestTableName)
	if len(errs) > 0 {
		t.Errorf("Cannot save event to event_test table: %v", errs[0])
	}
	err = persister.PopulateBlockDataFromDB(eventTestTableType)
	if err != nil {
		t.Errorf("Cannot fill persistence, %v", err)
	}
	if civilEventsFromContract2[1].LogPayload().BlockNumber !=
		persister.eventToBlockData[common.HexToAddress(contractAddress)]["Application"].BlockNumber {
		t.Errorf("Block number is not what it should be")
	}
}