mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
* Bump golangci-lint and Go CI versions * Bump golangci-lint version * Address nitterinos
410 lines
8.9 KiB
Go
410 lines
8.9 KiB
Go
package ticker
|
|
|
|
import (
|
|
"log"
|
|
"math/rand"
|
|
"os"
|
|
"strconv"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/thrasher-corp/gocryptotrader/currency"
|
|
"github.com/thrasher-corp/gocryptotrader/dispatch"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
err := dispatch.Start(1, dispatch.DefaultJobsLimit)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
cpyMux = service.mux
|
|
|
|
os.Exit(m.Run())
|
|
}
|
|
|
|
var cpyMux *dispatch.Mux
|
|
|
|
func TestSubscribeTicker(t *testing.T) {
|
|
_, err := SubscribeTicker("", currency.Pair{}, asset.Item(""))
|
|
if err == nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
|
|
p := currency.NewPair(currency.BTC, currency.USD)
|
|
|
|
// force error
|
|
service.mux = nil
|
|
err = ProcessTicker(&Price{
|
|
Pair: p,
|
|
ExchangeName: "subscribetest",
|
|
AssetType: asset.Spot})
|
|
if err == nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
|
|
sillyP := p
|
|
sillyP.Base = currency.GALA_NEO
|
|
err = ProcessTicker(&Price{
|
|
Pair: sillyP,
|
|
ExchangeName: "subscribetest",
|
|
AssetType: asset.Spot})
|
|
if err == nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
|
|
sillyP.Quote = currency.AAA
|
|
err = ProcessTicker(&Price{
|
|
Pair: sillyP,
|
|
ExchangeName: "subscribetest",
|
|
AssetType: asset.Spot})
|
|
if err == nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
|
|
err = ProcessTicker(&Price{
|
|
Pair: sillyP,
|
|
ExchangeName: "subscribetest",
|
|
AssetType: "silly",
|
|
})
|
|
if err == nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
// reinstate mux
|
|
service.mux = cpyMux
|
|
|
|
err = ProcessTicker(&Price{
|
|
Pair: p,
|
|
ExchangeName: "subscribetest",
|
|
AssetType: asset.Spot})
|
|
if err != nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
|
|
_, err = SubscribeTicker("subscribetest", p, asset.Spot)
|
|
if err != nil {
|
|
t.Error("cannot subscribe to ticker", err)
|
|
}
|
|
}
|
|
|
|
func TestSubscribeToExchangeTickers(t *testing.T) {
|
|
_, err := SubscribeToExchangeTickers("")
|
|
if err == nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
|
|
p := currency.NewPair(currency.BTC, currency.USD)
|
|
|
|
err = ProcessTicker(&Price{
|
|
Pair: p,
|
|
ExchangeName: "subscribeExchangeTest",
|
|
AssetType: asset.Spot})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = SubscribeToExchangeTickers("subscribeExchangeTest")
|
|
if err != nil {
|
|
t.Error("error cannot be nil", err)
|
|
}
|
|
}
|
|
|
|
func TestGetTicker(t *testing.T) {
|
|
newPair, err := currency.NewPairFromStrings("BTC", "USD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
priceStruct := Price{
|
|
Pair: newPair,
|
|
Last: 1200,
|
|
High: 1298,
|
|
Low: 1148,
|
|
Bid: 1195,
|
|
Ask: 1220,
|
|
Volume: 5,
|
|
PriceATH: 1337,
|
|
ExchangeName: "bitfinex",
|
|
AssetType: asset.Spot,
|
|
}
|
|
|
|
err = ProcessTicker(&priceStruct)
|
|
if err != nil {
|
|
t.Fatal("ProcessTicker error", err)
|
|
}
|
|
|
|
tickerPrice, err := GetTicker("bitfinex", newPair, asset.Spot)
|
|
if err != nil {
|
|
t.Errorf("Ticker GetTicker init error: %s", err)
|
|
}
|
|
if !tickerPrice.Pair.Equal(newPair) {
|
|
t.Error("ticker tickerPrice.CurrencyPair value is incorrect")
|
|
}
|
|
|
|
_, err = GetTicker("blah", newPair, asset.Spot)
|
|
if err == nil {
|
|
t.Fatal("TestGetTicker returned nil error on invalid exchange")
|
|
}
|
|
|
|
newPair.Base = currency.ETH
|
|
_, err = GetTicker("bitfinex", newPair, asset.Spot)
|
|
if err == nil {
|
|
t.Fatal("TestGetTicker returned ticker for invalid first currency")
|
|
}
|
|
|
|
btcltcPair, err := currency.NewPairFromStrings("BTC", "LTC")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
_, err = GetTicker("bitfinex", btcltcPair, asset.Spot)
|
|
if err == nil {
|
|
t.Fatal("TestGetTicker returned ticker for invalid second currency")
|
|
}
|
|
|
|
priceStruct.PriceATH = 9001
|
|
priceStruct.Pair.Base = currency.ETH
|
|
priceStruct.AssetType = "futures_3m"
|
|
err = ProcessTicker(&priceStruct)
|
|
if err != nil {
|
|
t.Fatal("ProcessTicker error", err)
|
|
}
|
|
|
|
tickerPrice, err = GetTicker("bitfinex", newPair, "futures_3m")
|
|
if err != nil {
|
|
t.Errorf("Ticker GetTicker init error: %s", err)
|
|
}
|
|
|
|
if tickerPrice.PriceATH != 9001 {
|
|
t.Error("ticker tickerPrice.PriceATH value is incorrect")
|
|
}
|
|
|
|
_, err = GetTicker("bitfinex", newPair, "meowCats")
|
|
if err == nil {
|
|
t.Error("Ticker GetTicker error cannot be nil")
|
|
}
|
|
|
|
priceStruct.AssetType = "meowCats"
|
|
err = ProcessTicker(&priceStruct)
|
|
if err != nil {
|
|
t.Fatal("ProcessTicker error", err)
|
|
}
|
|
|
|
// process update again
|
|
err = ProcessTicker(&priceStruct)
|
|
if err != nil {
|
|
t.Fatal("ProcessTicker error", err)
|
|
}
|
|
}
|
|
|
|
func TestProcessTicker(t *testing.T) { // non-appending function to tickers
|
|
exchName := "bitstamp"
|
|
newPair, err := currency.NewPairFromStrings("BTC", "USD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
priceStruct := Price{
|
|
Last: 1200,
|
|
High: 1298,
|
|
Low: 1148,
|
|
Bid: 1195,
|
|
Ask: 1220,
|
|
Volume: 5,
|
|
PriceATH: 1337,
|
|
}
|
|
|
|
err = ProcessTicker(&priceStruct)
|
|
if err == nil {
|
|
t.Fatal("empty exchange should throw an err")
|
|
}
|
|
|
|
priceStruct.ExchangeName = exchName
|
|
|
|
// test for empty pair
|
|
err = ProcessTicker(&priceStruct)
|
|
if err == nil {
|
|
t.Fatal("empty pair should throw an err")
|
|
}
|
|
|
|
// test for empty asset type
|
|
priceStruct.Pair = newPair
|
|
err = ProcessTicker(&priceStruct)
|
|
if err == nil {
|
|
t.Fatal("ProcessTicker error cannot be nil")
|
|
}
|
|
priceStruct.AssetType = asset.Spot
|
|
// now process a valid ticker
|
|
err = ProcessTicker(&priceStruct)
|
|
if err != nil {
|
|
t.Fatal("ProcessTicker error", err)
|
|
}
|
|
result, err := GetTicker(exchName, newPair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal("TestProcessTicker failed to create and return a new ticker")
|
|
}
|
|
if !result.Pair.Equal(newPair) {
|
|
t.Fatal("TestProcessTicker pair mismatch")
|
|
}
|
|
|
|
// now test for processing a pair with a different quote currency
|
|
newPair, err = currency.NewPairFromStrings("BTC", "AUD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
priceStruct.Pair = newPair
|
|
err = ProcessTicker(&priceStruct)
|
|
if err != nil {
|
|
t.Fatal("ProcessTicker error", err)
|
|
}
|
|
_, err = GetTicker(exchName, newPair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal("TestProcessTicker failed to create and return a new ticker")
|
|
}
|
|
_, err = GetTicker(exchName, newPair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal("TestProcessTicker failed to return an existing ticker")
|
|
}
|
|
|
|
// now test for processing a pair which has a different base currency
|
|
newPair, err = currency.NewPairFromStrings("LTC", "AUD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
priceStruct.Pair = newPair
|
|
err = ProcessTicker(&priceStruct)
|
|
if err != nil {
|
|
t.Fatal("ProcessTicker error", err)
|
|
}
|
|
_, err = GetTicker(exchName, newPair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal("TestProcessTicker failed to create and return a new ticker")
|
|
}
|
|
_, err = GetTicker(exchName, newPair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal("TestProcessTicker failed to return an existing ticker")
|
|
}
|
|
|
|
type quick struct {
|
|
Name string
|
|
P currency.Pair
|
|
TP Price
|
|
}
|
|
|
|
var testArray []quick
|
|
|
|
_ = rand.NewSource(time.Now().Unix())
|
|
|
|
var wg sync.WaitGroup
|
|
var sm sync.Mutex
|
|
|
|
var catastrophicFailure bool
|
|
for i := 0; i < 500; i++ {
|
|
if catastrophicFailure {
|
|
break
|
|
}
|
|
|
|
wg.Add(1)
|
|
go func() {
|
|
// nolint:gosec // no need to import crypo/rand for testing
|
|
newName := "Exchange" + strconv.FormatInt(rand.Int63(), 10)
|
|
newPairs, err := currency.NewPairFromStrings("BTC"+strconv.FormatInt(rand.Int63(), 10), // nolint:gosec // no need to import crypo/rand for testing
|
|
"USD"+strconv.FormatInt(rand.Int63(), 10)) // nolint:gosec // no need to import crypo/rand for testing
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
tp := Price{
|
|
Pair: newPairs,
|
|
Last: rand.Float64(), // nolint:gosec // no need to import crypo/rand for testing
|
|
ExchangeName: newName,
|
|
AssetType: asset.Spot,
|
|
}
|
|
|
|
sm.Lock()
|
|
err = ProcessTicker(&tp)
|
|
if err != nil {
|
|
t.Error(err)
|
|
catastrophicFailure = true
|
|
return
|
|
}
|
|
|
|
testArray = append(testArray, quick{Name: newName, P: newPairs, TP: tp})
|
|
sm.Unlock()
|
|
wg.Done()
|
|
}()
|
|
}
|
|
|
|
if catastrophicFailure {
|
|
t.Fatal("ProcessTicker error")
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
for _, test := range testArray {
|
|
wg.Add(1)
|
|
fatalErr := false
|
|
go func(test quick) {
|
|
result, err := GetTicker(test.Name, test.P, asset.Spot)
|
|
if err != nil {
|
|
fatalErr = true
|
|
return
|
|
}
|
|
|
|
if result.Last != test.TP.Last {
|
|
t.Error("TestProcessTicker failed bad values")
|
|
}
|
|
|
|
wg.Done()
|
|
}(test)
|
|
|
|
if fatalErr {
|
|
t.Fatal("TestProcessTicker failed to retrieve new ticker")
|
|
}
|
|
}
|
|
wg.Wait()
|
|
}
|
|
|
|
func TestSetItemID(t *testing.T) {
|
|
err := service.SetItemID(nil, "")
|
|
if err == nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
|
|
err = service.SetItemID(&Price{}, "")
|
|
if err == nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
|
|
p := currency.NewPair(currency.CYC, currency.CYG)
|
|
|
|
service.mux = nil
|
|
err = service.SetItemID(&Price{Pair: p, ExchangeName: "SetItemID"}, "setitemid")
|
|
if err == nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
|
|
service.mux = cpyMux
|
|
}
|
|
|
|
func TestGetAssociation(t *testing.T) {
|
|
_, err := service.GetAssociations(nil, "")
|
|
if err == nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
|
|
p := currency.NewPair(currency.CYC, currency.CYG)
|
|
|
|
service.mux = nil
|
|
|
|
_, err = service.GetAssociations(&Price{Pair: p, ExchangeName: "GetAssociation"}, "getassociation")
|
|
if err == nil {
|
|
t.Error("error cannot be nil")
|
|
}
|
|
|
|
service.mux = cpyMux
|
|
}
|