github.com/bitfinexcom/bitfinex-api-go@v0.0.0-20210608095005-9e0b26f200fb/tests/integration/v2/live_websocket_public_test.go (about)

     1  package tests
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"log"
     7  	"sync"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/book"
    12  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/candle"
    13  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/common"
    14  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/ticker"
    15  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/trade"
    16  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/tradeexecution"
    17  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/tradeexecutionupdate"
    18  	"github.com/bitfinexcom/bitfinex-api-go/v2"
    19  	"github.com/bitfinexcom/bitfinex-api-go/v2/websocket"
    20  )
    21  
    22  // wait2 will wait for at least "count" messages on channel "ch" within time "t", or return an error
    23  func wait2(ch <-chan interface{}, count int, bc <-chan error, t time.Duration) error {
    24  	c := make(chan interface{})
    25  	go func() {
    26  		<-ch
    27  		close(c)
    28  	}()
    29  	select {
    30  	case <-bc:
    31  		return fmt.Errorf("transport closed while waiting")
    32  	case <-c:
    33  		return nil // normal
    34  	case <-time.After(t):
    35  		return fmt.Errorf("timed out waiting")
    36  	}
    37  }
    38  
    39  func wait(wg *sync.WaitGroup, bc <-chan error, to time.Duration) error {
    40  	c := make(chan struct{})
    41  	go func() {
    42  		defer close(c)
    43  		wg.Wait()
    44  	}()
    45  	select {
    46  	case <-bc:
    47  		return fmt.Errorf("websocket closed while waiting") // timed out
    48  	case <-c:
    49  		return nil // completed normally
    50  	case <-time.After(to):
    51  		return fmt.Errorf("timed out waiting") // timed out
    52  	}
    53  }
    54  
    55  func TestPublicTicker(t *testing.T) {
    56  	c := websocket.New()
    57  
    58  	err := c.Connect()
    59  	if err != nil {
    60  		t.Fatal("Error connecting to web socket : ", err)
    61  	}
    62  	defer c.Close()
    63  
    64  	subs := make(chan interface{}, 10)
    65  	unsubs := make(chan interface{}, 10)
    66  	infos := make(chan interface{}, 10)
    67  	tick := make(chan interface{}, 100)
    68  
    69  	errch := make(chan error)
    70  	go func() {
    71  		// nolint:megacheck
    72  		for {
    73  			select {
    74  			case msg := <-c.Listen():
    75  				if msg == nil {
    76  					return
    77  				}
    78  				log.Printf("recv msg: %#v", msg)
    79  				switch m := msg.(type) {
    80  				case error:
    81  					errch <- msg.(error)
    82  				case *websocket.UnsubscribeEvent:
    83  					unsubs <- m
    84  				case *websocket.SubscribeEvent:
    85  					subs <- m
    86  				case *websocket.InfoEvent:
    87  					infos <- m
    88  				case *ticker.Snapshot:
    89  					tick <- m
    90  				case *ticker.Ticker:
    91  					tick <- m
    92  				default:
    93  					t.Logf("test recv: %#v", msg)
    94  				}
    95  			}
    96  		}
    97  	}()
    98  
    99  	ctx, cxl := context.WithTimeout(context.Background(), time.Second*5)
   100  	defer cxl()
   101  	id, err := c.SubscribeTicker(ctx, common.TradingPrefix+bitfinex.BTCUSD)
   102  	if err != nil {
   103  		t.Fatal(err)
   104  	}
   105  
   106  	if err := wait2(tick, 1, errch, 2*time.Second); err != nil {
   107  		t.Fatalf("failed to receive ticker message from websocket: %s", err)
   108  	}
   109  
   110  	err = c.Unsubscribe(ctx, id)
   111  	if err != nil {
   112  		t.Fatal(err)
   113  	}
   114  
   115  	if err := wait2(unsubs, 1, errch, 2*time.Second); err != nil {
   116  		t.Errorf("failed to receive unsubscribe message from websocket: %s", err)
   117  	}
   118  }
   119  
   120  func TestPublicTrades(t *testing.T) {
   121  	c := websocket.New()
   122  	wg := sync.WaitGroup{}
   123  	wg.Add(3) // 1. Info with version, 2. Subscription event, 3. 3 x data message
   124  
   125  	err := c.Connect()
   126  	if err != nil {
   127  		t.Fatal("Error connecting to web socket : ", err)
   128  	}
   129  	defer c.Close()
   130  
   131  	subs := make(chan interface{}, 10)
   132  	unsubs := make(chan interface{}, 10)
   133  	infos := make(chan interface{}, 10)
   134  	trades := make(chan interface{}, 100)
   135  
   136  	errch := make(chan error)
   137  	go func() {
   138  		// nolint:megacheck
   139  		for {
   140  			select {
   141  			case msg := <-c.Listen():
   142  				if msg == nil {
   143  					return
   144  				}
   145  				log.Printf("recv msg: %#v", msg)
   146  				switch m := msg.(type) {
   147  				case error:
   148  					errch <- msg.(error)
   149  				case *websocket.UnsubscribeEvent:
   150  					unsubs <- m
   151  				case *websocket.SubscribeEvent:
   152  					subs <- m
   153  				case *websocket.InfoEvent:
   154  					infos <- m
   155  				case *tradeexecutionupdate.Snapshot:
   156  					trades <- m
   157  				case *trade.Trade:
   158  					trades <- m
   159  				case *tradeexecutionupdate.TradeExecutionUpdate:
   160  					trades <- m
   161  				case *tradeexecution.TradeExecution:
   162  					trades <- m
   163  				case *trade.Snapshot:
   164  					trades <- m
   165  				default:
   166  					t.Logf("test recv: %#v", msg)
   167  				}
   168  			}
   169  		}
   170  	}()
   171  
   172  	ctx, cxl := context.WithTimeout(context.Background(), time.Second*5)
   173  	defer cxl()
   174  	id, err := c.SubscribeTrades(ctx, common.TradingPrefix+bitfinex.BTCUSD)
   175  	if err != nil {
   176  		t.Fatal(err)
   177  	}
   178  
   179  	if err := wait2(trades, 1, errch, 2*time.Second); err != nil {
   180  		t.Errorf("failed to receive trade message from websocket: %s", err)
   181  	}
   182  
   183  	err = c.Unsubscribe(ctx, id)
   184  	if err != nil {
   185  		t.Fatal(err)
   186  	}
   187  
   188  	if err := wait2(unsubs, 1, errch, 2*time.Second); err != nil {
   189  		t.Errorf("failed to receive unsubscribe message from websocket: %s", err)
   190  	}
   191  }
   192  
   193  func TestPublicBooks(t *testing.T) {
   194  	c := websocket.New()
   195  	wg := sync.WaitGroup{}
   196  	wg.Add(3) // 1. Info with version, 2. Subscription event, 3. data message
   197  
   198  	err := c.Connect()
   199  	if err != nil {
   200  		t.Fatal("Error connecting to web socket : ", err)
   201  	}
   202  	defer c.Close()
   203  
   204  	subs := make(chan interface{}, 10)
   205  	unsubs := make(chan interface{}, 10)
   206  	infos := make(chan interface{}, 10)
   207  	books := make(chan interface{}, 100)
   208  
   209  	errch := make(chan error)
   210  	go func() {
   211  		// nolint:megacheck
   212  		for {
   213  			select {
   214  			case msg := <-c.Listen():
   215  				if msg == nil {
   216  					return
   217  				}
   218  				log.Printf("recv msg: %#v", msg)
   219  				switch m := msg.(type) {
   220  				case error:
   221  					errch <- msg.(error)
   222  				case *websocket.UnsubscribeEvent:
   223  					unsubs <- m
   224  				case *websocket.SubscribeEvent:
   225  					subs <- m
   226  				case *websocket.InfoEvent:
   227  					infos <- m
   228  				case *book.Snapshot:
   229  					books <- m
   230  				case *book.Book:
   231  					books <- m
   232  				default:
   233  					t.Logf("test recv: %#v", msg)
   234  				}
   235  			}
   236  		}
   237  	}()
   238  
   239  	ctx, cxl := context.WithTimeout(context.Background(), time.Second*5)
   240  	defer cxl()
   241  	id, err := c.SubscribeBook(ctx, common.TradingPrefix+bitfinex.BTCUSD, common.Precision0, common.FrequencyRealtime, 1)
   242  	if err != nil {
   243  		t.Fatal(err)
   244  	}
   245  
   246  	if err := wait2(books, 1, errch, 5*time.Second); err != nil {
   247  		t.Fatalf("failed to receive book update message from websocket: %s", err)
   248  	}
   249  
   250  	err = c.Unsubscribe(ctx, id)
   251  	if err != nil {
   252  		t.Fatal(err)
   253  	}
   254  
   255  	if err := wait2(unsubs, 1, errch, 5*time.Second); err != nil {
   256  		t.Errorf("failed to receive unsubscribe message from websocket: %s", err)
   257  	}
   258  }
   259  
   260  func TestPublicCandles(t *testing.T) {
   261  	c := websocket.New()
   262  	wg := sync.WaitGroup{}
   263  	wg.Add(3) // 1. Info with version, 2. Subscription event, 3. data message
   264  
   265  	err := c.Connect()
   266  	if err != nil {
   267  		t.Fatal("Error connecting to web socket : ", err)
   268  	}
   269  	defer c.Close()
   270  
   271  	subs := make(chan interface{}, 10)
   272  	unsubs := make(chan interface{}, 10)
   273  	infos := make(chan interface{}, 10)
   274  	candles := make(chan interface{}, 100)
   275  
   276  	errch := make(chan error)
   277  	go func() {
   278  		// nolint:megacheck
   279  		for {
   280  			select {
   281  			case msg := <-c.Listen():
   282  				if msg == nil {
   283  					return
   284  				}
   285  				log.Printf("recv msg: %#v", msg)
   286  				switch m := msg.(type) {
   287  				case error:
   288  					errch <- msg.(error)
   289  				case *websocket.UnsubscribeEvent:
   290  					unsubs <- m
   291  				case *websocket.SubscribeEvent:
   292  					subs <- m
   293  				case *websocket.InfoEvent:
   294  					infos <- m
   295  				case *candle.Candle:
   296  					candles <- m
   297  				case *candle.Snapshot:
   298  					candles <- m
   299  				default:
   300  					t.Logf("test recv: %#v", msg)
   301  				}
   302  			}
   303  		}
   304  	}()
   305  
   306  	ctx, cxl := context.WithTimeout(context.Background(), time.Second*5)
   307  	defer cxl()
   308  	id, err := c.SubscribeCandles(ctx, common.TradingPrefix+bitfinex.BTCUSD, common.OneMonth)
   309  	if err != nil {
   310  		t.Fatal(err)
   311  	}
   312  
   313  	if err := wait2(candles, 1, errch, 2*time.Second); err != nil {
   314  		t.Errorf("failed to receive a candle message from websocket: %s", err)
   315  	}
   316  
   317  	err = c.Unsubscribe(ctx, id)
   318  	if err != nil {
   319  		t.Fatal(err)
   320  	}
   321  
   322  	if err := wait2(unsubs, 1, errch, 2*time.Second); err != nil {
   323  		t.Errorf("failed to receive an unsubscribe message from websocket: %s", err)
   324  	}
   325  }