@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/pubsub"
"github.com/tendermint/tendermint/libs/pubsub"
@ -35,8 +36,8 @@ func TestSubscribe(t *testing.T) {
subscription , err := s . Subscribe ( ctx , clientID , query . Empty { } )
subscription , err := s . Subscribe ( ctx , clientID , query . Empty { } )
require . NoError ( t , err )
require . NoError ( t , err )
assert . Equal ( t , 1 , s . NumClients ( ) )
assert . Equal ( t , 1 , s . NumClientSubscriptions ( clientID ) )
require . Equal ( t , 1 , s . NumClients ( ) )
require . Equal ( t , 1 , s . NumClientSubscriptions ( clientID ) )
err = s . Publish ( ctx , "Ka-Zar" )
err = s . Publish ( ctx , "Ka-Zar" )
require . NoError ( t , err )
require . NoError ( t , err )
@ -47,13 +48,13 @@ func TestSubscribe(t *testing.T) {
defer close ( published )
defer close ( published )
err := s . Publish ( ctx , "Quicksilver" )
err := s . Publish ( ctx , "Quicksilver" )
assert . NoError ( t , err )
require . NoError ( t , err )
err = s . Publish ( ctx , "Asylum" )
err = s . Publish ( ctx , "Asylum" )
assert . NoError ( t , err )
require . NoError ( t , err )
err = s . Publish ( ctx , "Ivan" )
err = s . Publish ( ctx , "Ivan" )
assert . NoError ( t , err )
require . NoError ( t , err )
} ( )
} ( )
select {
select {
@ -77,11 +78,11 @@ func TestSubscribeWithCapacity(t *testing.T) {
} )
} )
ctx := context . Background ( )
ctx := context . Background ( )
assert . Panics ( t , func ( ) {
require . Panics ( t , func ( ) {
_ , err = s . Subscribe ( ctx , clientID , query . Empty { } , - 1 )
_ , err = s . Subscribe ( ctx , clientID , query . Empty { } , - 1 )
require . NoError ( t , err )
require . NoError ( t , err )
} )
} )
assert . Panics ( t , func ( ) {
require . Panics ( t , func ( ) {
_ , err = s . Subscribe ( ctx , clientID , query . Empty { } , 0 )
_ , err = s . Subscribe ( ctx , clientID , query . Empty { } , 0 )
require . NoError ( t , err )
require . NoError ( t , err )
} )
} )
@ -112,10 +113,10 @@ func TestSubscribeUnbuffered(t *testing.T) {
defer close ( published )
defer close ( published )
err := s . Publish ( ctx , "Ultron" )
err := s . Publish ( ctx , "Ultron" )
assert . NoError ( t , err )
require . NoError ( t , err )
err = s . Publish ( ctx , "Darkhawk" )
err = s . Publish ( ctx , "Darkhawk" )
assert . NoError ( t , err )
require . NoError ( t , err )
} ( )
} ( )
select {
select {
@ -152,8 +153,8 @@ func TestSlowClientIsRemovedWithErrOutOfCapacity(t *testing.T) {
func TestDifferentClients ( t * testing . T ) {
func TestDifferentClients ( t * testing . T ) {
s := pubsub . NewServer ( )
s := pubsub . NewServer ( )
s . SetLogger ( log . TestingLogger ( ) )
s . SetLogger ( log . TestingLogger ( ) )
err := s . Start ( )
require . NoError ( t , err )
require . NoError ( t , s . Start ( ) )
t . Cleanup ( func ( ) {
t . Cleanup ( func ( ) {
if err := s . Stop ( ) ; err != nil {
if err := s . Stop ( ) ; err != nil {
t . Error ( err )
t . Error ( err )
@ -161,10 +162,18 @@ func TestDifferentClients(t *testing.T) {
} )
} )
ctx := context . Background ( )
ctx := context . Background ( )
subscription1 , err := s . Subscribe ( ctx , "client-1" , query . MustParse ( "tm.events.type='NewBlock'" ) )
subscription1 , err := s . Subscribe ( ctx , "client-1" , query . MustParse ( "tm.events.type='NewBlock'" ) )
require . NoError ( t , err )
require . NoError ( t , err )
err = s . PublishWithEvents ( ctx , "Iceman" , map [ string ] [ ] string { "tm.events.type" : { "NewBlock" } } )
require . NoError ( t , err )
events := [ ] abci . Event {
{
Type : "tm.events" ,
Attributes : [ ] abci . EventAttribute { { Key : "type" , Value : "NewBlock" } } ,
} ,
}
require . NoError ( t , s . PublishWithEvents ( ctx , "Iceman" , events ) )
assertReceive ( t , "Iceman" , subscription1 . Out ( ) )
assertReceive ( t , "Iceman" , subscription1 . Out ( ) )
subscription2 , err := s . Subscribe (
subscription2 , err := s . Subscribe (
@ -173,12 +182,19 @@ func TestDifferentClients(t *testing.T) {
query . MustParse ( "tm.events.type='NewBlock' AND abci.account.name='Igor'" ) ,
query . MustParse ( "tm.events.type='NewBlock' AND abci.account.name='Igor'" ) ,
)
)
require . NoError ( t , err )
require . NoError ( t , err )
err = s . PublishWithEvents (
ctx ,
"Ultimo" ,
map [ string ] [ ] string { "tm.events.type" : { "NewBlock" } , "abci.account.name" : { "Igor" } } ,
)
require . NoError ( t , err )
events = [ ] abci . Event {
{
Type : "tm.events" ,
Attributes : [ ] abci . EventAttribute { { Key : "type" , Value : "NewBlock" } } ,
} ,
{
Type : "abci.account" ,
Attributes : [ ] abci . EventAttribute { { Key : "name" , Value : "Igor" } } ,
} ,
}
require . NoError ( t , s . PublishWithEvents ( ctx , "Ultimo" , events ) )
assertReceive ( t , "Ultimo" , subscription1 . Out ( ) )
assertReceive ( t , "Ultimo" , subscription1 . Out ( ) )
assertReceive ( t , "Ultimo" , subscription2 . Out ( ) )
assertReceive ( t , "Ultimo" , subscription2 . Out ( ) )
@ -188,16 +204,25 @@ func TestDifferentClients(t *testing.T) {
query . MustParse ( "tm.events.type='NewRoundStep' AND abci.account.name='Igor' AND abci.invoice.number = 10" ) ,
query . MustParse ( "tm.events.type='NewRoundStep' AND abci.account.name='Igor' AND abci.invoice.number = 10" ) ,
)
)
require . NoError ( t , err )
require . NoError ( t , err )
err = s . PublishWithEvents ( ctx , "Valeria Richards" , map [ string ] [ ] string { "tm.events.type" : { "NewRoundStep" } } )
require . NoError ( t , err )
assert . Zero ( t , len ( subscription3 . Out ( ) ) )
events = [ ] abci . Event {
{
Type : "tm.events" ,
Attributes : [ ] abci . EventAttribute { { Key : "type" , Value : "NewRoundStep" } } ,
} ,
}
require . NoError ( t , s . PublishWithEvents ( ctx , "Valeria Richards" , events ) )
require . Zero ( t , len ( subscription3 . Out ( ) ) )
}
}
func TestSubscribeDuplicateKeys ( t * testing . T ) {
func TestSubscribeDuplicateKeys ( t * testing . T ) {
ctx := context . Background ( )
ctx := context . Background ( )
s := pubsub . NewServer ( )
s := pubsub . NewServer ( )
s . SetLogger ( log . TestingLogger ( ) )
s . SetLogger ( log . TestingLogger ( ) )
require . NoError ( t , s . Start ( ) )
require . NoError ( t , s . Start ( ) )
t . Cleanup ( func ( ) {
t . Cleanup ( func ( ) {
if err := s . Stop ( ) ; err != nil {
if err := s . Stop ( ) ; err != nil {
t . Error ( err )
t . Error ( err )
@ -230,15 +255,26 @@ func TestSubscribeDuplicateKeys(t *testing.T) {
sub , err := s . Subscribe ( ctx , fmt . Sprintf ( "client-%d" , i ) , query . MustParse ( tc . query ) )
sub , err := s . Subscribe ( ctx , fmt . Sprintf ( "client-%d" , i ) , query . MustParse ( tc . query ) )
require . NoError ( t , err )
require . NoError ( t , err )
err = s . PublishWithEvents (
ctx ,
"Iceman" ,
map [ string ] [ ] string {
"transfer.sender" : { "foo" , "bar" , "baz" } ,
"withdraw.rewards" : { "1" , "17" , "22" } ,
events := [ ] abci . Event {
{
Type : "transfer" ,
Attributes : [ ] abci . EventAttribute {
{ Key : "sender" , Value : "foo" } ,
{ Key : "sender" , Value : "bar" } ,
{ Key : "sender" , Value : "baz" } ,
} ,
} ,
} ,
)
require . NoError ( t , err )
{
Type : "withdraw" ,
Attributes : [ ] abci . EventAttribute {
{ Key : "rewards" , Value : "1" } ,
{ Key : "rewards" , Value : "17" } ,
{ Key : "rewards" , Value : "22" } ,
} ,
} ,
}
require . NoError ( t , s . PublishWithEvents ( ctx , "Iceman" , events ) )
if tc . expected != nil {
if tc . expected != nil {
assertReceive ( t , tc . expected , sub . Out ( ) )
assertReceive ( t , tc . expected , sub . Out ( ) )
@ -264,16 +300,22 @@ func TestClientSubscribesTwice(t *testing.T) {
subscription1 , err := s . Subscribe ( ctx , clientID , q )
subscription1 , err := s . Subscribe ( ctx , clientID , q )
require . NoError ( t , err )
require . NoError ( t , err )
err = s . PublishWithEvents ( ctx , "Goblin Queen" , map [ string ] [ ] string { "tm.events.type" : { "NewBlock" } } )
require . NoError ( t , err )
events := [ ] abci . Event {
{
Type : "tm.events" ,
Attributes : [ ] abci . EventAttribute { { Key : "type" , Value : "NewBlock" } } ,
} ,
}
require . NoError ( t , s . PublishWithEvents ( ctx , "Goblin Queen" , events ) )
assertReceive ( t , "Goblin Queen" , subscription1 . Out ( ) )
assertReceive ( t , "Goblin Queen" , subscription1 . Out ( ) )
subscription2 , err := s . Subscribe ( ctx , clientID , q )
subscription2 , err := s . Subscribe ( ctx , clientID , q )
require . Error ( t , err )
require . Error ( t , err )
require . Nil ( t , subscription2 )
require . Nil ( t , subscription2 )
err = s . PublishWithEvents ( ctx , "Spider-Man" , map [ string ] [ ] string { "tm.events.type" : { "NewBlock" } } )
require . NoError ( t , err )
require . NoError ( t , s . PublishWithEvents ( ctx , "Spider-Man" , events ) )
assertReceive ( t , "Spider-Man" , subscription1 . Out ( ) )
assertReceive ( t , "Spider-Man" , subscription1 . Out ( ) )
}
}
@ -298,7 +340,7 @@ func TestUnsubscribe(t *testing.T) {
err = s . Publish ( ctx , "Nick Fury" )
err = s . Publish ( ctx , "Nick Fury" )
require . NoError ( t , err )
require . NoError ( t , err )
assert . Zero ( t , len ( subscription . Out ( ) ) , "Should not receive anything after Unsubscribe" )
require . Zero ( t , len ( subscription . Out ( ) ) , "Should not receive anything after Unsubscribe" )
assertCanceled ( t , subscription , pubsub . ErrUnsubscribed )
assertCanceled ( t , subscription , pubsub . ErrUnsubscribed )
}
}
@ -325,9 +367,9 @@ func TestClientUnsubscribesTwice(t *testing.T) {
err = s . Unsubscribe ( ctx , pubsub . UnsubscribeArgs {
err = s . Unsubscribe ( ctx , pubsub . UnsubscribeArgs {
Subscriber : clientID ,
Subscriber : clientID ,
Query : query . MustParse ( "tm.events.type='NewBlock'" ) } )
Query : query . MustParse ( "tm.events.type='NewBlock'" ) } )
assert . Equal ( t , pubsub . ErrSubscriptionNotFound , err )
require . Equal ( t , pubsub . ErrSubscriptionNotFound , err )
err = s . UnsubscribeAll ( ctx , clientID )
err = s . UnsubscribeAll ( ctx , clientID )
assert . Equal ( t , pubsub . ErrSubscriptionNotFound , err )
require . Equal ( t , pubsub . ErrSubscriptionNotFound , err )
}
}
func TestResubscribe ( t * testing . T ) {
func TestResubscribe ( t * testing . T ) {
@ -376,8 +418,8 @@ func TestUnsubscribeAll(t *testing.T) {
err = s . Publish ( ctx , "Nick Fury" )
err = s . Publish ( ctx , "Nick Fury" )
require . NoError ( t , err )
require . NoError ( t , err )
assert . Zero ( t , len ( subscription1 . Out ( ) ) , "Should not receive anything after UnsubscribeAll" )
assert . Zero ( t , len ( subscription2 . Out ( ) ) , "Should not receive anything after UnsubscribeAll" )
require . Zero ( t , len ( subscription1 . Out ( ) ) , "Should not receive anything after UnsubscribeAll" )
require . Zero ( t , len ( subscription2 . Out ( ) ) , "Should not receive anything after UnsubscribeAll" )
assertCanceled ( t , subscription1 , pubsub . ErrUnsubscribed )
assertCanceled ( t , subscription1 , pubsub . ErrUnsubscribed )
assertCanceled ( t , subscription2 , pubsub . ErrUnsubscribed )
assertCanceled ( t , subscription2 , pubsub . ErrUnsubscribed )
@ -387,7 +429,7 @@ func TestBufferCapacity(t *testing.T) {
s := pubsub . NewServer ( pubsub . BufferCapacity ( 2 ) )
s := pubsub . NewServer ( pubsub . BufferCapacity ( 2 ) )
s . SetLogger ( log . TestingLogger ( ) )
s . SetLogger ( log . TestingLogger ( ) )
assert . Equal ( t , 2 , s . BufferCapacity ( ) )
require . Equal ( t , 2 , s . BufferCapacity ( ) )
ctx := context . Background ( )
ctx := context . Background ( )
err := s . Publish ( ctx , "Nighthawk" )
err := s . Publish ( ctx , "Nighthawk" )
@ -397,9 +439,10 @@ func TestBufferCapacity(t *testing.T) {
ctx , cancel := context . WithTimeout ( ctx , 10 * time . Millisecond )
ctx , cancel := context . WithTimeout ( ctx , 10 * time . Millisecond )
defer cancel ( )
defer cancel ( )
err = s . Publish ( ctx , "Ironclad" )
err = s . Publish ( ctx , "Ironclad" )
if assert . Error ( t , err ) {
if assert . Error ( t , err ) {
assert . Equal ( t , context . DeadlineExceeded , err )
require . Equal ( t , context . DeadlineExceeded , err )
}
}
}
}
@ -447,12 +490,18 @@ func benchmarkNClients(n int, b *testing.B) {
b . ReportAllocs ( )
b . ReportAllocs ( )
b . ResetTimer ( )
b . ResetTimer ( )
for i := 0 ; i < b . N ; i ++ {
for i := 0 ; i < b . N ; i ++ {
err = s . PublishWithEvents (
ctx ,
"Gamora" ,
map [ string ] [ ] string { "abci.Account.Owner" : { "Ivan" } , "abci.Invoices.Number" : { string ( rune ( i ) ) } } ,
)
require . NoError ( b , err )
events := [ ] abci . Event {
{
Type : "abci.Account" ,
Attributes : [ ] abci . EventAttribute { { Key : "Owner" , Value : "Ivan" } } ,
} ,
{
Type : "abci.Invoices" ,
Attributes : [ ] abci . EventAttribute { { Key : "Number" , Value : string ( rune ( i ) ) } } ,
} ,
}
require . NoError ( b , s . PublishWithEvents ( ctx , "Gamora" , events ) )
}
}
}
}
@ -487,10 +536,20 @@ func benchmarkNClientsOneQuery(n int, b *testing.B) {
b . ReportAllocs ( )
b . ReportAllocs ( )
b . ResetTimer ( )
b . ResetTimer ( )
for i := 0 ; i < b . N ; i ++ {
for i := 0 ; i < b . N ; i ++ {
err = s . PublishWithEvents ( ctx , "Gamora" , map [ string ] [ ] string { "abci.Account.Owner" : { "Ivan" } ,
"abci.Invoices.Number" : { "1" } } )
require . NoError ( b , err )
events := [ ] abci . Event {
{
Type : "abci.Account" ,
Attributes : [ ] abci . EventAttribute { { Key : "Owner" , Value : "Ivan" } } ,
} ,
{
Type : "abci.Invoices" ,
Attributes : [ ] abci . EventAttribute { { Key : "Number" , Value : "1" } } ,
} ,
}
require . NoError ( b , s . PublishWithEvents ( ctx , "Gamora" , events ) )
}
}
}
}
@ -499,7 +558,7 @@ func benchmarkNClientsOneQuery(n int, b *testing.B) {
func assertReceive ( t * testing . T , expected interface { } , ch <- chan pubsub . Message , msgAndArgs ... interface { } ) {
func assertReceive ( t * testing . T , expected interface { } , ch <- chan pubsub . Message , msgAndArgs ... interface { } ) {
select {
select {
case actual := <- ch :
case actual := <- ch :
assert . Equal ( t , expected , actual . Data ( ) , msgAndArgs ... )
require . Equal ( t , expected , actual . Data ( ) , msgAndArgs ... )
case <- time . After ( 1 * time . Second ) :
case <- time . After ( 1 * time . Second ) :
t . Errorf ( "expected to receive %v from the channel, got nothing after 1s" , expected )
t . Errorf ( "expected to receive %v from the channel, got nothing after 1s" , expected )
debug . PrintStack ( )
debug . PrintStack ( )
@ -508,6 +567,6 @@ func assertReceive(t *testing.T, expected interface{}, ch <-chan pubsub.Message,
func assertCanceled ( t * testing . T , subscription * pubsub . Subscription , err error ) {
func assertCanceled ( t * testing . T , subscription * pubsub . Subscription , err error ) {
_ , ok := <- subscription . Canceled ( )
_ , ok := <- subscription . Canceled ( )
assert . False ( t , ok )
assert . Equal ( t , err , subscription . Err ( ) )
require . False ( t , ok )
require . Equal ( t , err , subscription . Err ( ) )
}
}