github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/vent/sqldb/sqldb_postgres_test.go (about) 1 // +build integration 2 3 package sqldb_test 4 5 import ( 6 "encoding/json" 7 "fmt" 8 "strconv" 9 "testing" 10 "time" 11 12 "github.com/hyperledger/burrow/vent/sqldb/adapters" 13 "github.com/hyperledger/burrow/vent/test" 14 "github.com/hyperledger/burrow/vent/types" 15 "github.com/lib/pq" 16 "github.com/stretchr/testify/require" 17 ) 18 19 var tables = types.DefaultSQLTableNames 20 var columns = types.DefaultSQLColumnNames 21 22 func TestPostgresSynchronizeDB(t *testing.T) { 23 testSynchronizeDB(t, test.PostgresVentConfig("")) 24 } 25 26 func TestPostgresCleanDB(t *testing.T) { 27 testCleanDB(t, test.PostgresVentConfig("")) 28 } 29 30 func TestPostgresSetBlock(t *testing.T) { 31 testSetBlock(t, test.PostgresVentConfig("")) 32 } 33 34 func TestRestore(t *testing.T) { 35 testRestore(t, test.PostgresVentConfig("")) 36 } 37 38 func TestPostgresBlockNotification(t *testing.T) { 39 cfg := test.PostgresVentConfig("") 40 db, closeDB := test.NewTestDB(t, cfg) 41 defer closeDB() 42 43 errp := db.Ping() 44 require.NoError(t, errp) 45 46 functionName := "notify_height" 47 channelName := "height_notification" 48 pad := db.DBAdapter.(*adapters.PostgresAdapter) 49 50 // Run twice to show idempotency 51 for i := 0; i < 2; i++ { 52 query := pad.CreateNotifyFunctionQuery(functionName, channelName, columns.Height) 53 _, err := db.DB.Exec(query) 54 require.NoError(t, err) 55 56 query = pad.CreateTriggerQuery("notify_height_trigger", tables.Log, functionName) 57 _, err = db.DB.Exec(query) 58 require.NoError(t, err) 59 } 60 61 listener := pq.NewListener(cfg.DBURL, time.Second, time.Second*20, func(event pq.ListenerEventType, err error) { 62 require.NoError(t, err) 63 }) 64 err := listener.Listen(channelName) 65 require.NoError(t, err) 66 67 // new block 68 str, dat := getBlock() 69 70 errCh := make(chan error) 71 go func() { 72 type payload struct { 73 Height string `json:"_height"` 74 } 75 for n := range listener.NotificationChannel() { 76 pl := new(payload) 77 err := json.Unmarshal([]byte(n.Extra), pl) 78 if err != nil { 79 errCh <- err 80 return 81 } 82 if pl.Height != "" { 83 if strconv.FormatUint(dat.BlockHeight, 10) != pl.Height { 84 errCh <- fmt.Errorf("got height %s from notification but expected %d", 85 pl.Height, dat.BlockHeight) 86 } 87 errCh <- nil 88 return 89 } 90 } 91 }() 92 93 // Set it 94 err = db.SetBlock(test.ChainID, str, dat) 95 require.NoError(t, err) 96 97 // read 98 _, err = db.LastBlockHeight(test.ChainID) 99 require.NoError(t, err) 100 101 _, err = db.GetBlock(test.ChainID, dat.BlockHeight) 102 require.NoError(t, err) 103 104 const timeout = 2 * time.Second 105 select { 106 case <-time.After(timeout): 107 t.Fatalf("timed out waiting for notification after %s", timeout) 108 case err = <-errCh: 109 require.NoError(t, err) 110 } 111 }