Improvement: Speeding up slow tests (#707)

* Speeds up tests

* Reduces time.Sleeps, lowers CreateTestBot complexity. Breaks things

* Removal of unecessary config reads. Parallel tests. Lower times

* Speeds up recent trades results

* mini update

* zoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooom

* Removes the dupes

* Lint

* post cherrypick

* Fix rare kraken data race

* Fixes banking global issues. Fixes postgres trades

* rmline for appveyor test

* Expands timeout in event that channel is closed before send

* Fix data race

* No rows, no bows and definitely no shows

* Removes parallel from createsnapshot tests

* Extends timedmutext test a smidge. Exchange fatality

* Shorter end timeframe and bigger candle
This commit is contained in:
Scott
2021-07-07 12:42:03 +10:00
committed by GitHub
parent 7815d0a1f4
commit 63257ce4ca
70 changed files with 1834 additions and 1121 deletions

View File

@@ -86,13 +86,6 @@ func NewFromConfig(cfg *config.Config, templatePath, output string, bot *engine.
return nil, err
}
e, err := bt.setupExchangeSettings(cfg)
if err != nil {
return nil, err
}
bt.Exchange = &e
buyRule := config.MinMax{
MinimumSize: cfg.PortfolioSettings.BuySide.MinimumSize,
MaximumSize: cfg.PortfolioSettings.BuySide.MaximumSize,
@@ -158,22 +151,6 @@ func NewFromConfig(cfg *config.Config, templatePath, output string, bot *engine.
if err != nil {
return nil, err
}
for i := range e.CurrencySettings {
var lookup *settings.Settings
lookup, err = p.SetupCurrencySettingsMap(e.CurrencySettings[i].ExchangeName, e.CurrencySettings[i].AssetType, e.CurrencySettings[i].CurrencyPair)
if err != nil {
return nil, err
}
lookup.Fee = e.CurrencySettings[i].TakerFee
lookup.Leverage = e.CurrencySettings[i].Leverage
lookup.BuySideSizing = e.CurrencySettings[i].BuySide
lookup.SellSideSizing = e.CurrencySettings[i].SellSide
lookup.InitialFunds = e.CurrencySettings[i].InitialFunds
lookup.ComplianceManager = compliance.Manager{
Snapshots: []compliance.Snapshot{},
}
}
bt.Portfolio = p
bt.Strategy, err = strategies.LoadStrategyByName(cfg.StrategySettings.Name, cfg.StrategySettings.SimultaneousSignalProcessing)
if err != nil {
@@ -197,6 +174,29 @@ func NewFromConfig(cfg *config.Config, templatePath, output string, bot *engine.
bt.Statistic = stats
reports.Statistics = stats
e, err := bt.setupExchangeSettings(cfg)
if err != nil {
return nil, err
}
bt.Exchange = &e
for i := range e.CurrencySettings {
var lookup *settings.Settings
lookup, err = p.SetupCurrencySettingsMap(e.CurrencySettings[i].ExchangeName, e.CurrencySettings[i].AssetType, e.CurrencySettings[i].CurrencyPair)
if err != nil {
return nil, err
}
lookup.Fee = e.CurrencySettings[i].TakerFee
lookup.Leverage = e.CurrencySettings[i].Leverage
lookup.BuySideSizing = e.CurrencySettings[i].BuySide
lookup.SellSideSizing = e.CurrencySettings[i].SellSide
lookup.InitialFunds = e.CurrencySettings[i].InitialFunds
lookup.ComplianceManager = compliance.Manager{
Snapshots: []compliance.Snapshot{},
}
}
bt.Portfolio = p
cfg.PrintSetting()
return bt, nil
@@ -418,7 +418,6 @@ func getFees(exch gctexchange.IBotExchange, fPair currency.Pair) (makerFee, take
// loadData will create kline data from the sources defined in start config files. It can exist from databases, csv or API endpoints
// it can also be generated from trade data which will be converted into kline data
func (bt *BackTest) loadData(cfg *config.Config, exch gctexchange.IBotExchange, fPair currency.Pair, a asset.Item) (*kline.DataFromKline, error) {
log.Infof(log.BackTester, "loading data for %v %v %v...\n", exch.GetName(), a, fPair)
if exch == nil {
return nil, engine.ErrExchangeNotFound
}
@@ -429,7 +428,6 @@ func (bt *BackTest) loadData(cfg *config.Config, exch gctexchange.IBotExchange,
cfg.DataSettings.CSVData == nil {
return nil, errNoDataSource
}
resp := &kline.DataFromKline{}
if (cfg.DataSettings.APIData != nil && cfg.DataSettings.DatabaseData != nil) ||
(cfg.DataSettings.APIData != nil && cfg.DataSettings.LiveData != nil) ||
(cfg.DataSettings.APIData != nil && cfg.DataSettings.CSVData != nil) ||
@@ -444,6 +442,8 @@ func (bt *BackTest) loadData(cfg *config.Config, exch gctexchange.IBotExchange,
return nil, err
}
log.Infof(log.BackTester, "loading data for %v %v %v...\n", exch.GetName(), a, fPair)
resp := &kline.DataFromKline{}
switch {
case cfg.DataSettings.CSVData != nil:
if cfg.DataSettings.Interval <= 0 {
@@ -941,18 +941,15 @@ func (bt *BackTest) loadLiveDataLoop(resp *kline.DataFromKline, cfg *config.Conf
return
}
resp.Item = *candles
err = bt.loadLiveData(resp, cfg, exch, fPair, a, startDate, dataType)
if err != nil {
log.Error(log.BackTester, err)
return
}
loadNewDataTicker := time.NewTicker(time.Second * 30)
loadNewDataTimer := time.NewTimer(time.Second * 5)
for {
select {
case <-bt.shutdown:
return
case <-loadNewDataTicker.C:
case <-loadNewDataTimer.C:
log.Infof(log.BackTester, "fetching data for %v %v %v %v", exch.GetName(), a, fPair, cfg.DataSettings.Interval)
loadNewDataTimer.Reset(time.Second * 30)
err = bt.loadLiveData(resp, cfg, exch, fPair, a, startDate, dataType)
if err != nil {
log.Error(log.BackTester, err)
@@ -963,6 +960,15 @@ func (bt *BackTest) loadLiveDataLoop(resp *kline.DataFromKline, cfg *config.Conf
}
func (bt *BackTest) loadLiveData(resp *kline.DataFromKline, cfg *config.Config, exch gctexchange.IBotExchange, fPair currency.Pair, a asset.Item, startDate time.Time, dataType int64) error {
if resp == nil {
return errNilData
}
if cfg == nil {
return errNilConfig
}
if exch == nil {
return errNilExchange
}
candles, err := live.LoadData(
exch,
dataType,
@@ -972,6 +978,7 @@ func (bt *BackTest) loadLiveData(resp *kline.DataFromKline, cfg *config.Config,
if err != nil {
return err
}
resp.Item.Candles = append(resp.Item.Candles, candles.Candles...)
_, err = exch.FetchOrderbook(fPair, a)
if err != nil {
@@ -983,7 +990,7 @@ func (bt *BackTest) loadLiveData(resp *kline.DataFromKline, cfg *config.Config,
return nil
}
endDate := candles.Candles[len(candles.Candles)-1].Time.Add(cfg.DataSettings.Interval)
if resp.Range.Ranges == nil {
if resp.Range == nil || resp.Range.Ranges == nil {
dataRange, err := gctkline.CalculateCandleDateRanges(
startDate,
endDate,

View File

@@ -20,10 +20,13 @@ import (
"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/statistics"
"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/statistics/currencystatistics"
"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/strategies"
"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/strategies/base"
"github.com/thrasher-corp/gocryptotrader/backtester/eventhandlers/strategies/dollarcostaverage"
"github.com/thrasher-corp/gocryptotrader/backtester/report"
"github.com/thrasher-corp/gocryptotrader/common/convert"
gctconfig "github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/database"
"github.com/thrasher-corp/gocryptotrader/database/drivers"
"github.com/thrasher-corp/gocryptotrader/engine"
gctexchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
@@ -32,42 +35,54 @@ import (
const testExchange = "Bitstamp"
func newBotWithExchange() (*engine.Engine, gctexchange.IBotExchange) {
bot, err := engine.NewFromSettings(&engine.Settings{
ConfigFile: filepath.Join("..", "..", "testdata", "configtest.json"),
EnableDryRun: true,
}, nil)
func newBotWithExchange() *engine.Engine {
bot := &engine.Engine{
Config: &gctconfig.Config{
Exchanges: []gctconfig.ExchangeConfig{
{
Name: testExchange,
Enabled: true,
WebsocketTrafficTimeout: time.Second,
CurrencyPairs: &currency.PairsManager{
Pairs: map[asset.Item]*currency.PairStore{
asset.Spot: {
AssetEnabled: convert.BoolPtr(true),
Available: []currency.Pair{currency.NewPair(currency.BTC, currency.USD)},
Enabled: []currency.Pair{currency.NewPair(currency.BTC, currency.USD)},
ConfigFormat: &currency.PairFormat{},
RequestFormat: &currency.PairFormat{},
},
},
},
},
},
},
}
em := engine.SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
log.Fatal(err)
}
bot.ExchangeManager = engine.SetupExchangeManager()
err = bot.LoadExchange(testExchange, false, nil)
if err != nil {
log.Fatal(err)
}
exch := bot.GetExchangeByName(testExchange)
if exch == nil {
log.Fatal("expected not nil")
}
return bot, exch
exch.SetDefaults()
em.Add(exch)
bot.ExchangeManager = em
return bot
}
func TestNewFromConfig(t *testing.T) {
t.Parallel()
_, err := NewFromConfig(nil, "", "", nil)
if err == nil {
t.Error("expected error for nil config")
if !errors.Is(err, errNilConfig) {
t.Errorf("received %v, expected %v", err, errNilConfig)
}
cfg := &config.Config{
GoCryptoTraderConfigPath: filepath.Join("..", "..", "testdata", "configtest.json"),
}
cfg := &config.Config{}
_, err = NewFromConfig(cfg, "", "", nil)
if !errors.Is(err, errNilBot) {
t.Errorf("expected: %v, received %v", errNilBot, err)
}
bot, _ := newBotWithExchange()
bot := newBotWithExchange()
_, err = NewFromConfig(cfg, "", "", bot)
if !errors.Is(err, config.ErrNoCurrencySettings) {
t.Errorf("expected: %v, received %v", config.ErrNoCurrencySettings, err)
@@ -97,6 +112,12 @@ func TestNewFromConfig(t *testing.T) {
t.Errorf("expected: %v, received %v", engine.ErrExchangeNotFound, err)
}
cfg.StrategySettings = config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
"hello": "moto",
},
}
cfg.CurrencySettings[0].ExchangeName = testExchange
_, err = NewFromConfig(cfg, "", "", bot)
if !errors.Is(err, errNoDataSource) {
@@ -105,7 +126,6 @@ func TestNewFromConfig(t *testing.T) {
cfg.CurrencySettings[0].Base = "BTC"
cfg.CurrencySettings[0].Quote = "USD"
cfg.DataSettings.APIData = &config.APIData{
StartDate: time.Time{},
EndDate: time.Time{},
@@ -121,7 +141,7 @@ func TestNewFromConfig(t *testing.T) {
t.Errorf("expected: %v, received %v", config.ErrStartEndUnset, err)
}
cfg.DataSettings.APIData.StartDate = time.Now().Add(-time.Hour)
cfg.DataSettings.APIData.StartDate = time.Now().Add(-time.Minute)
cfg.DataSettings.APIData.EndDate = time.Now()
cfg.DataSettings.APIData.InclusiveEndDate = true
_, err = NewFromConfig(cfg, "", "", bot)
@@ -129,19 +149,7 @@ func TestNewFromConfig(t *testing.T) {
t.Errorf("expected: %v, received %v", errIntervalUnset, err)
}
cfg.DataSettings.Interval = gctkline.FifteenMin.Duration()
_, err = NewFromConfig(cfg, "", "", bot)
if !errors.Is(err, base.ErrStrategyNotFound) {
t.Errorf("expected: %v, received %v", base.ErrStrategyNotFound, err)
}
cfg.StrategySettings = config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
"hello": "moto",
},
}
cfg.DataSettings.Interval = gctkline.OneMin.Duration()
cfg.CurrencySettings[0].MakerFee = 1337
cfg.CurrencySettings[0].TakerFee = 1337
_, err = NewFromConfig(cfg, "", "", bot)
@@ -150,140 +158,246 @@ func TestNewFromConfig(t *testing.T) {
}
}
func TestLoadData(t *testing.T) {
func TestLoadDataAPI(t *testing.T) {
t.Parallel()
cfg := &config.Config{
GoCryptoTraderConfigPath: filepath.Join("..", "..", "testdata", "configtest.json"),
}
cfg.CurrencySettings = []config.CurrencySettings{
{
ExchangeName: "test",
Asset: "test",
Base: "test",
Quote: "test",
},
}
cfg.CurrencySettings[0].ExchangeName = "binance"
cfg.CurrencySettings[0].Asset = asset.Spot.String()
cfg.CurrencySettings[0].Base = "BTC"
cfg.CurrencySettings[0].Quote = "USDT"
cfg.CurrencySettings[0].InitialFunds = 1337
cfg.DataSettings.APIData = &config.APIData{
StartDate: time.Time{},
EndDate: time.Time{},
}
cfg.DataSettings.APIData.StartDate = time.Now().Add(-time.Hour)
cfg.DataSettings.APIData.EndDate = time.Now()
cfg.DataSettings.Interval = gctkline.FifteenMin.Duration()
cfg.DataSettings.DataType = common.CandleStr
cfg.StrategySettings = config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
"hello": "moto",
},
}
cfg.CurrencySettings[0].MakerFee = 1337
cfg.CurrencySettings[0].TakerFee = 1337
bot, exch := newBotWithExchange()
_, err := NewFromConfig(cfg, "", "", bot)
if err != nil {
t.Error(err)
}
bt := BackTest{
Reports: &report.Data{},
Bot: &engine.Engine{},
}
cp := currency.NewPair(currency.BTC, currency.USDT)
cfg := &config.Config{
CurrencySettings: []config.CurrencySettings{
{
ExchangeName: "Binance",
Asset: asset.Spot.String(),
Base: cp.Base.String(),
Quote: cp.Quote.String(),
InitialFunds: 1337,
Leverage: config.Leverage{},
BuySide: config.MinMax{},
SellSide: config.MinMax{},
MakerFee: 1337,
TakerFee: 1337,
},
},
DataSettings: config.DataSettings{
DataType: common.CandleStr,
Interval: gctkline.OneMin.Duration(),
APIData: &config.APIData{
StartDate: time.Now().Add(-time.Minute),
EndDate: time.Now(),
}},
StrategySettings: config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
"hello": "moto",
},
},
}
em := engine.ExchangeManager{}
exch, err := em.NewExchangeByName("Binance")
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
b := exch.GetBase()
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp},
Enabled: currency.Pairs{cp},
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
cp := currency.NewPair(currency.BTC, currency.USD)
_, err = bt.loadData(cfg, exch, cp, asset.Spot)
if err != nil {
t.Error(err)
}
}
cfg.DataSettings.APIData = nil
cfg.DataSettings.DatabaseData = &config.DatabaseData{
StartDate: time.Now().Add(-time.Hour),
EndDate: time.Now(),
ConfigOverride: nil,
InclusiveEndDate: true,
func TestLoadDataDatabase(t *testing.T) {
t.Parallel()
bt := BackTest{
Reports: &report.Data{},
Bot: &engine.Engine{
Config: &gctconfig.Config{Database: database.Config{}},
},
}
cfg.DataSettings.DataType = common.CandleStr
cfg.DataSettings.Interval = gctkline.FifteenMin.Duration()
cp := currency.NewPair(currency.BTC, currency.USDT)
cfg := &config.Config{
CurrencySettings: []config.CurrencySettings{
{
ExchangeName: "Binance",
Asset: asset.Spot.String(),
Base: cp.Base.String(),
Quote: cp.Quote.String(),
InitialFunds: 1337,
Leverage: config.Leverage{},
BuySide: config.MinMax{},
SellSide: config.MinMax{},
MakerFee: 1337,
TakerFee: 1337,
},
},
DataSettings: config.DataSettings{
DataType: common.CandleStr,
Interval: gctkline.OneMin.Duration(),
DatabaseData: &config.DatabaseData{
ConfigOverride: &database.Config{
Enabled: true,
Driver: "sqlite3",
ConnectionDetails: drivers.ConnectionDetails{
Database: "gocryptotrader.db",
},
},
StartDate: time.Now().Add(-time.Minute),
EndDate: time.Now(),
InclusiveEndDate: true,
}},
StrategySettings: config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
"hello": "moto",
},
},
}
em := engine.ExchangeManager{}
exch, err := em.NewExchangeByName("Binance")
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
b := exch.GetBase()
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp},
Enabled: currency.Pairs{cp},
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
bt.Bot = bot
_, err = bt.loadData(cfg, exch, cp, asset.Spot)
if err != nil && !strings.Contains(err.Error(), "unable to retrieve data from GoCryptoTrader database") {
t.Error(err)
}
}
cfg.DataSettings.DatabaseData = nil
cfg.DataSettings.CSVData = &config.CSVData{
FullPath: "test",
func TestLoadDataCSV(t *testing.T) {
t.Parallel()
bt := BackTest{
Reports: &report.Data{},
Bot: &engine.Engine{},
}
cp := currency.NewPair(currency.BTC, currency.USDT)
cfg := &config.Config{
CurrencySettings: []config.CurrencySettings{
{
ExchangeName: "Binance",
Asset: asset.Spot.String(),
Base: cp.Base.String(),
Quote: cp.Quote.String(),
InitialFunds: 1337,
Leverage: config.Leverage{},
BuySide: config.MinMax{},
SellSide: config.MinMax{},
MakerFee: 1337,
TakerFee: 1337,
},
},
DataSettings: config.DataSettings{
DataType: common.CandleStr,
Interval: gctkline.OneMin.Duration(),
CSVData: &config.CSVData{
FullPath: "test",
}},
StrategySettings: config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
"hello": "moto",
},
},
}
em := engine.ExchangeManager{}
exch, err := em.NewExchangeByName("Binance")
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
b := exch.GetBase()
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp},
Enabled: currency.Pairs{cp},
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
_, err = bt.loadData(cfg, exch, cp, asset.Spot)
if err != nil &&
!strings.Contains(err.Error(), "The system cannot find the file specified.") &&
!strings.Contains(err.Error(), "no such file or directory") {
t.Error(err)
}
cfg.DataSettings.CSVData = nil
cfg.DataSettings.LiveData = &config.LiveData{
APIKeyOverride: "test",
APISecretOverride: "test",
APIClientIDOverride: "test",
API2FAOverride: "test",
APISubaccountOverride: "test",
RealOrders: true,
}
func TestLoadDataLive(t *testing.T) {
t.Parallel()
bt := BackTest{
Reports: &report.Data{},
Bot: &engine.Engine{},
shutdown: make(chan struct{}),
}
cp := currency.NewPair(currency.BTC, currency.USDT)
cfg := &config.Config{
CurrencySettings: []config.CurrencySettings{
{
ExchangeName: "Binance",
Asset: asset.Spot.String(),
Base: cp.Base.String(),
Quote: cp.Quote.String(),
InitialFunds: 1337,
Leverage: config.Leverage{},
BuySide: config.MinMax{},
SellSide: config.MinMax{},
MakerFee: 1337,
TakerFee: 1337,
},
},
DataSettings: config.DataSettings{
DataType: common.CandleStr,
Interval: gctkline.OneMin.Duration(),
LiveData: &config.LiveData{
APIKeyOverride: "test",
APISecretOverride: "test",
APIClientIDOverride: "test",
API2FAOverride: "test",
RealOrders: true,
}},
StrategySettings: config.StrategySettings{
Name: dollarcostaverage.Name,
CustomSettings: map[string]interface{}{
"hello": "moto",
},
},
}
em := engine.ExchangeManager{}
exch, err := em.NewExchangeByName("Binance")
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
b := exch.GetBase()
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp},
Enabled: currency.Pairs{cp},
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
_, err = bt.loadData(cfg, exch, cp, asset.Spot)
if err != nil {
t.Error(err)
}
}
func TestLoadDatabaseData(t *testing.T) {
t.Parallel()
cp := currency.NewPair(currency.BTC, currency.USD)
_, err := loadDatabaseData(nil, "", cp, "", -1)
if err != nil && !strings.Contains(err.Error(), "nil config data received") {
t.Error(err)
}
cfg := &config.Config{
DataSettings: config.DataSettings{
DatabaseData: &config.DatabaseData{
StartDate: time.Time{},
EndDate: time.Time{},
ConfigOverride: nil,
},
},
GoCryptoTraderConfigPath: filepath.Join("..", "..", "testdata", "configtest.json"),
}
_, err = loadDatabaseData(cfg, "", cp, "", -1)
if !errors.Is(err, config.ErrStartEndUnset) {
t.Errorf("expected %v, received %v", config.ErrStartEndUnset, err)
}
cfg.DataSettings.DatabaseData.StartDate = time.Now().Add(-time.Hour)
cfg.DataSettings.DatabaseData.EndDate = time.Now()
_, err = loadDatabaseData(cfg, "", cp, "", -1)
if !errors.Is(err, errIntervalUnset) {
t.Errorf("expected %v, received %v", errIntervalUnset, err)
}
cfg.DataSettings.Interval = gctkline.OneDay.Duration()
_, err = loadDatabaseData(cfg, "", cp, "", -1)
if err != nil && !strings.Contains(err.Error(), "could not retrieve database data") {
t.Error(err)
}
cfg.DataSettings.DataType = common.CandleStr
_, err = loadDatabaseData(cfg, "", cp, "", common.DataCandle)
if err != nil && !strings.Contains(err.Error(), "exchange, base, quote, asset, interval, start & end cannot be empty") {
t.Error(err)
}
_, err = loadDatabaseData(cfg, testExchange, cp, asset.Spot, common.DataCandle)
if err != nil && !strings.Contains(err.Error(), "database support is disabled") {
t.Error(err)
}
bt.Stop()
}
func TestLoadLiveData(t *testing.T) {
@@ -399,7 +513,7 @@ func TestFullCycle(t *testing.T) {
if err != nil {
t.Error(err)
}
bot, _ := newBotWithExchange()
bot := newBotWithExchange()
bt := BackTest{
Bot: bot,
@@ -493,7 +607,7 @@ func TestFullCycleMulti(t *testing.T) {
if err != nil {
t.Error(err)
}
bot, _ := newBotWithExchange()
bot := newBotWithExchange()
bt := BackTest{
Bot: bot,

View File

@@ -23,6 +23,8 @@ var (
errIntervalUnset = errors.New("candle interval unset")
errUnhandledDatatype = errors.New("unhandled datatype")
errLiveDataTimeout = errors.New("no data returned in 5 minutes, shutting down")
errNilData = errors.New("nil data received")
errNilExchange = errors.New("nil exchange received")
)
// BackTest is the main holder of all backtesting functionality

View File

@@ -2,59 +2,42 @@ package api
import (
"errors"
"log"
"os"
"path/filepath"
"testing"
"time"
"github.com/thrasher-corp/gocryptotrader/backtester/common"
"github.com/thrasher-corp/gocryptotrader/common/convert"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/engine"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
gctkline "github.com/thrasher-corp/gocryptotrader/exchanges/kline"
)
const testExchange = "binance"
var (
bot *engine.Engine
exch exchange.IBotExchange
)
func TestMain(m *testing.M) {
var err error
bot, err = engine.NewFromSettings(&engine.Settings{
ConfigFile: filepath.Join("..", "..", "..", "..", "testdata", "configtest.json"),
EnableDryRun: true,
}, nil)
if err != nil {
log.Fatal(err)
}
bot.ExchangeManager = engine.SetupExchangeManager()
err = bot.LoadExchange(testExchange, false, nil)
if err != nil {
log.Fatal(err)
}
exch = bot.GetExchangeByName(testExchange)
if exch == nil {
log.Fatal("expected binance")
}
os.Exit(m.Run())
}
func TestLoadCandles(t *testing.T) {
t.Parallel()
tt1 := time.Now().Add(-time.Hour).Round(gctkline.OneHour.Duration())
tt2 := time.Now().Round(gctkline.OneHour.Duration())
interval := gctkline.OneHour
em := engine.SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
cp := currency.NewPair(currency.BTC, currency.USDT)
b := exch.GetBase()
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp},
Enabled: currency.Pairs{cp},
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
tt1 := time.Now().Add(-time.Minute).Round(gctkline.OneMin.Duration())
tt2 := time.Now().Round(gctkline.OneMin.Duration())
interval := gctkline.OneMin
a := asset.Spot
p := currency.NewPair(currency.BTC, currency.USDT)
var data *gctkline.Item
var err error
data, err = LoadData(common.DataCandle, tt1, tt2, interval.Duration(), exch, p, a)
data, err = LoadData(common.DataCandle, tt1, tt2, interval.Duration(), exch, cp, a)
if err != nil {
t.Fatal(err)
}
@@ -62,7 +45,7 @@ func TestLoadCandles(t *testing.T) {
t.Error("expected candles")
}
_, err = LoadData(-1, tt1, tt2, interval.Duration(), exch, p, a)
_, err = LoadData(-1, tt1, tt2, interval.Duration(), exch, cp, a)
if !errors.Is(err, common.ErrInvalidDataType) {
t.Errorf("expected '%v' received '%v'", err, common.ErrInvalidDataType)
}
@@ -70,14 +53,27 @@ func TestLoadCandles(t *testing.T) {
func TestLoadTrades(t *testing.T) {
t.Parallel()
interval := gctkline.FifteenMin
tt1 := time.Now().Add(-time.Minute * 30).Round(interval.Duration())
em := engine.SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
cp := currency.NewPair(currency.BTC, currency.USDT)
b := exch.GetBase()
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp},
Enabled: currency.Pairs{cp},
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
interval := gctkline.OneMin
tt1 := time.Now().Add(-time.Minute * 2).Round(interval.Duration())
tt2 := time.Now().Round(interval.Duration())
a := asset.Spot
p := currency.NewPair(currency.BTC, currency.USDT)
var err error
var data *gctkline.Item
data, err = LoadData(common.DataTrade, tt1, tt2, interval.Duration(), exch, p, a)
data, err = LoadData(common.DataTrade, tt1, tt2, interval.Duration(), exch, cp, a)
if err != nil {
t.Fatal(err)
}

View File

@@ -22,7 +22,7 @@ func LoadData(exch exchange.IBotExchange, dataType int64, interval time.Duration
candles, err = exch.GetHistoricCandles(
fPair,
a,
time.Now().Add(-interval), // multiplied by 2 to ensure the latest candle is always included
time.Now().Add(-interval*2), // multiplied by 2 to ensure the latest candle is always included
time.Now(),
kline.Interval(interval))
if err != nil {
@@ -30,9 +30,7 @@ func LoadData(exch exchange.IBotExchange, dataType int64, interval time.Duration
}
case common.DataTrade:
var trades []trade.Data
trades, err = exch.GetRecentTrades(
fPair,
a)
trades, err = exch.GetHistoricTrades(fPair, a, time.Now().Add(-interval*2), time.Now()) // multiplied by 2 to ensure the latest candle is always included
if err != nil {
return nil, err
}

View File

@@ -2,47 +2,48 @@ package live
import (
"errors"
"log"
"path/filepath"
"testing"
"github.com/thrasher-corp/gocryptotrader/backtester/common"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/common/convert"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/engine"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
gctkline "github.com/thrasher-corp/gocryptotrader/exchanges/kline"
)
const testExchange = "FTX"
const testExchange = "binance"
func TestLoadCandles(t *testing.T) {
t.Parallel()
interval := gctkline.FifteenMin
bot := new(engine.Engine)
bot.Config = &config.Config{}
err := bot.Config.LoadConfig(filepath.Join("..", "..", "..", "..", "testdata", "configtest.json"), true)
if err != nil {
t.Fatalf("SetupTest: Failed to load config: %s", err)
}
bot.ExchangeManager = engine.SetupExchangeManager()
err = bot.LoadExchange(testExchange, false, nil)
if err != nil {
log.Fatal(err)
}
exch := bot.ExchangeManager.GetExchangeByName(testExchange)
interval := gctkline.OneHour
cp1 := currency.NewPair(currency.BTC, currency.USDT)
a := asset.Spot
p := currency.NewPair(currency.BTC, currency.USD)
em := engine.SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
}
pFormat := &currency.PairFormat{Uppercase: true}
b := exch.GetBase()
exch.SetDefaults()
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp1},
Enabled: currency.Pairs{cp1},
AssetEnabled: convert.BoolPtr(true),
RequestFormat: pFormat,
ConfigFormat: pFormat,
}
var data *gctkline.Item
data, err = LoadData(exch, common.DataCandle, interval.Duration(), p, a)
data, err = LoadData(exch, common.DataCandle, interval.Duration(), cp1, a)
if err != nil {
t.Fatal(err)
}
if len(data.Candles) == 0 {
t.Error("expected candles")
}
_, err = LoadData(exch, -1, interval.Duration(), p, a)
_, err = LoadData(exch, -1, interval.Duration(), cp1, a)
if !errors.Is(err, common.ErrInvalidDataType) {
t.Errorf("expected '%v' received '%v'", err, common.ErrInvalidDataType)
}
@@ -50,28 +51,27 @@ func TestLoadCandles(t *testing.T) {
func TestLoadTrades(t *testing.T) {
t.Parallel()
interval := gctkline.FifteenMin
bot, err := engine.NewFromSettings(&engine.Settings{
ConfigFile: filepath.Join("..", "..", "..", "..", "testdata", "configtest.json"),
EnableDryRun: true,
}, nil)
if err != nil {
t.Error(err)
}
bot.ExchangeManager = engine.SetupExchangeManager()
err = bot.LoadExchange(testExchange, false, nil)
interval := gctkline.OneMin
cp1 := currency.NewPair(currency.BTC, currency.USDT)
a := asset.Spot
em := engine.SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
}
exch := bot.GetExchangeByName(testExchange)
if exch == nil {
t.Fatal("expected binance")
pFormat := &currency.PairFormat{Uppercase: true}
b := exch.GetBase()
exch.SetDefaults()
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp1},
Enabled: currency.Pairs{cp1},
AssetEnabled: convert.BoolPtr(true),
RequestFormat: pFormat,
ConfigFormat: pFormat,
}
a := asset.Spot
p := currency.NewPair(currency.BTC, currency.USDT)
var data *gctkline.Item
data, err = LoadData(exch, common.DataTrade, interval.Duration(), p, a)
data, err = LoadData(exch, common.DataTrade, interval.Duration(), cp1, a)
if err != nil {
t.Fatal(err)
}

View File

@@ -2,7 +2,6 @@ package exchange
import (
"errors"
"path/filepath"
"strings"
"testing"
"time"
@@ -132,14 +131,15 @@ func TestSizeOrder(t *testing.T) {
func TestPlaceOrder(t *testing.T) {
t.Parallel()
bot, err := engine.NewFromSettings(&engine.Settings{
ConfigFile: filepath.Join("..", "..", "..", "testdata", "configtest.json"),
EnableDryRun: true,
}, nil)
bot := &engine.Engine{}
var err error
em := engine.SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
}
em := engine.SetupExchangeManager()
exch.SetDefaults()
em.Add(exch)
bot.ExchangeManager = em
bot.OrderManager, err = engine.SetupOrderManager(em, &engine.CommunicationManager{}, &bot.ServicesWG, false)
if err != nil {
@@ -149,10 +149,7 @@ func TestPlaceOrder(t *testing.T) {
if err != nil {
t.Error(err)
}
err = bot.LoadExchange(testExchange, false, nil)
if err != nil {
t.Error(err)
}
e := Exchange{}
_, err = e.placeOrder(1, 1, false, true, nil, nil)
if !errors.Is(err, common.ErrNilEvent) {
@@ -185,15 +182,15 @@ func TestPlaceOrder(t *testing.T) {
func TestExecuteOrder(t *testing.T) {
t.Parallel()
bot, err := engine.NewFromSettings(&engine.Settings{
ConfigFile: filepath.Join("..", "..", "..", "testdata", "configtest.json"),
EnableDryRun: true,
}, nil)
bot := &engine.Engine{}
var err error
em := engine.SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
}
em := engine.SetupExchangeManager()
exch.SetDefaults()
em.Add(exch)
bot.ExchangeManager = em
bot.OrderManager, err = engine.SetupOrderManager(em, &engine.CommunicationManager{}, &bot.ServicesWG, false)
if err != nil {
@@ -203,20 +200,10 @@ func TestExecuteOrder(t *testing.T) {
if err != nil {
t.Error(err)
}
err = bot.LoadExchange(testExchange, false, nil)
if err != nil {
t.Error(err)
}
b := bot.GetExchangeByName(testExchange)
p := currency.NewPair(currency.BTC, currency.USDT)
a := asset.Spot
_, err = b.FetchOrderbook(p, a)
if err != nil {
t.Fatal(err)
}
limits, err := b.GetOrderExecutionLimits(a, p)
_, err = exch.FetchOrderbook(p, a)
if err != nil {
t.Fatal(err)
}
@@ -235,7 +222,6 @@ func TestExecuteOrder(t *testing.T) {
Leverage: config.Leverage{},
MinimumSlippageRate: 0,
MaximumSlippageRate: 1,
Limits: limits,
}
e := Exchange{
CurrencySettings: []Settings{cs},
@@ -292,38 +278,37 @@ func TestExecuteOrder(t *testing.T) {
func TestExecuteOrderBuySellSizeLimit(t *testing.T) {
t.Parallel()
bot, err := engine.NewFromSettings(&engine.Settings{
ConfigFile: filepath.Join("..", "..", "..", "testdata", "configtest.json"),
EnableDryRun: true,
}, nil)
bot := &engine.Engine{}
var err error
em := engine.SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
}
em := engine.SetupExchangeManager()
exch.SetDefaults()
em.Add(exch)
bot.ExchangeManager = em
bot.OrderManager, err = engine.SetupOrderManager(em, &engine.CommunicationManager{}, &bot.ServicesWG, false)
if err != nil {
t.Error(err)
}
err = bot.OrderManager.Start()
if err != nil {
t.Error(err)
}
err = bot.LoadExchange(testExchange, false, nil)
if err != nil {
t.Error(err)
}
b := bot.GetExchangeByName(testExchange)
p := currency.NewPair(currency.BTC, currency.USDT)
a := asset.Spot
_, err = b.FetchOrderbook(p, a)
_, err = exch.FetchOrderbook(p, a)
if err != nil {
t.Fatal(err)
}
limits, err := b.GetOrderExecutionLimits(a, p)
err = exch.UpdateOrderExecutionLimits(asset.Spot)
if err != nil {
t.Fatal(err)
}
limits, err := exch.GetOrderExecutionLimits(a, p)
if err != nil {
t.Fatal(err)
}

View File

@@ -14,10 +14,10 @@ func BenchmarkTimedMutexTime(b *testing.B) {
func TestConsistencyOfPanicFreeUnlock(t *testing.T) {
t.Parallel()
duration := 20 * time.Millisecond
duration := 20 * time.Microsecond
tm := NewTimedMutex(duration)
for i := 1; i <= 50; i++ {
testUnlockTime := time.Duration(i) * time.Millisecond
testUnlockTime := time.Duration(i) * time.Microsecond
tm.LockForDuration()
time.Sleep(testUnlockTime)
tm.UnlockIfLocked()
@@ -26,9 +26,9 @@ func TestConsistencyOfPanicFreeUnlock(t *testing.T) {
func TestUnlockAfterTimeout(t *testing.T) {
t.Parallel()
tm := NewTimedMutex(time.Second)
tm := NewTimedMutex(time.Nanosecond)
tm.LockForDuration()
time.Sleep(2 * time.Second)
time.Sleep(time.Millisecond * 200)
wasUnlocked := tm.UnlockIfLocked()
if wasUnlocked {
t.Error("Mutex should have been unlocked by timeout, not command")
@@ -37,9 +37,8 @@ func TestUnlockAfterTimeout(t *testing.T) {
func TestUnlockBeforeTimeout(t *testing.T) {
t.Parallel()
tm := NewTimedMutex(2 * time.Second)
tm := NewTimedMutex(20 * time.Millisecond)
tm.LockForDuration()
time.Sleep(time.Second)
wasUnlocked := tm.UnlockIfLocked()
if !wasUnlocked {
t.Error("Mutex should have been unlocked by command, not timeout")
@@ -53,7 +52,7 @@ func TestUnlockBeforeTimeout(t *testing.T) {
// the unlock occurs without this test panicking
func TestUnlockAtSameTimeAsTimeout(t *testing.T) {
t.Parallel()
duration := time.Second
duration := time.Millisecond
tm := NewTimedMutex(duration)
tm.LockForDuration()
time.Sleep(duration)
@@ -80,7 +79,7 @@ func TestMultipleUnlocks(t *testing.T) {
func TestJustWaitItOut(t *testing.T) {
t.Parallel()
tm := NewTimedMutex(1 * time.Second)
tm := NewTimedMutex(1 * time.Millisecond)
tm.LockForDuration()
time.Sleep(2 * time.Second)
time.Sleep(2 * time.Millisecond)
}

View File

@@ -8,12 +8,6 @@ import (
"github.com/thrasher-corp/gocryptotrader/config"
)
const (
verificationToken = ""
)
var s Slack
type group struct {
ID string `json:"id"`
Name string `json:"name"`
@@ -21,18 +15,17 @@ type group struct {
}
func TestSetup(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig("../../testdata/configtest.json", true)
if err != nil {
t.Fatal(err)
}
t.Parallel()
var s Slack
cfg := &config.Config{Communications: base.CommunicationsConfig{}}
commsCfg := cfg.GetCommunicationsConfig()
s.Setup(&commsCfg)
s.Verbose = true
}
func TestConnect(t *testing.T) {
t.Parallel()
var s Slack
err := s.Connect()
if err == nil {
t.Error("slack Connect() error cannot be nil")
@@ -41,6 +34,7 @@ func TestConnect(t *testing.T) {
func TestPushEvent(t *testing.T) {
t.Parallel()
var s Slack
err := s.PushEvent(base.Event{})
if err == nil {
t.Error("slack PushEvent() error cannot be nil")
@@ -49,6 +43,7 @@ func TestPushEvent(t *testing.T) {
func TestBuildURL(t *testing.T) {
t.Parallel()
var s Slack
v := s.BuildURL("lol123")
if v != "https://slack.com/api/rtm.start?token=lol123" {
t.Error("slack BuildURL() error")
@@ -56,6 +51,8 @@ func TestBuildURL(t *testing.T) {
}
func TestGetChannelsString(t *testing.T) {
t.Parallel()
var s Slack
s.Details.Channels = append(s.Details.Channels, struct {
ID string `json:"id"`
Name string `json:"name"`
@@ -78,6 +75,8 @@ func TestGetChannelsString(t *testing.T) {
}
func TestGetUsernameByID(t *testing.T) {
t.Parallel()
var s Slack
username := s.GetUsernameByID("1337")
if username != "" {
t.Error("slack GetUsernameByID() error")
@@ -99,6 +98,8 @@ func TestGetUsernameByID(t *testing.T) {
}
func TestGetIDByName(t *testing.T) {
t.Parallel()
var s Slack
id, err := s.GetIDByName("batman")
if err == nil || id != "" {
t.Error("slack GetIDByName() error")
@@ -116,6 +117,8 @@ func TestGetIDByName(t *testing.T) {
}
func TestGetGroupIDByName(t *testing.T) {
t.Parallel()
var s Slack
id, err := s.GetGroupIDByName("batman")
if err == nil || id != "" {
t.Error("slack GetGroupIDByName() error")
@@ -133,6 +136,8 @@ func TestGetGroupIDByName(t *testing.T) {
}
func TestGetChannelIDByName(t *testing.T) {
t.Parallel()
var s Slack
id, err := s.GetChannelIDByName("1337")
if err == nil || id != "" {
t.Error("slack GetChannelIDByName() error")
@@ -156,6 +161,8 @@ func TestGetChannelIDByName(t *testing.T) {
}
func TestGetUsersInGroup(t *testing.T) {
t.Parallel()
var s Slack
username := s.GetUsersInGroup("supergroup")
if len(username) != 0 {
t.Error("slack GetUsersInGroup() error")
@@ -175,6 +182,8 @@ func TestGetUsersInGroup(t *testing.T) {
}
func TestNewConnection(t *testing.T) {
t.Parallel()
var s Slack
err := s.NewConnection()
if err == nil {
t.Error("slack NewConnection() error")
@@ -182,6 +191,8 @@ func TestNewConnection(t *testing.T) {
}
func TestWebsocketConnect(t *testing.T) {
t.Parallel()
var s Slack
err := s.WebsocketConnect()
if err == nil {
t.Error("slack WebsocketConnect() error")
@@ -189,6 +200,8 @@ func TestWebsocketConnect(t *testing.T) {
}
func TestHandlePresenceChange(t *testing.T) {
t.Parallel()
var s Slack
var pres PresenceChange
pres.User = "1337"
pres.Presence = "Present"
@@ -206,6 +219,8 @@ func TestHandlePresenceChange(t *testing.T) {
}
func TestHandleMessageResponse(t *testing.T) {
t.Parallel()
var s Slack
var data WebsocketResponse
data.ReplyTo = 1
@@ -242,6 +257,8 @@ func TestHandleMessageResponse(t *testing.T) {
}
func TestHandleErrorResponse(t *testing.T) {
t.Parallel()
var s Slack
var data WebsocketResponse
err := s.handleErrorResponse(data)
if err == nil {
@@ -256,10 +273,14 @@ func TestHandleErrorResponse(t *testing.T) {
}
func TestHandleHelloResponse(t *testing.T) {
t.Parallel()
var s Slack
s.handleHelloResponse()
}
func TestHandleReconnectResponse(t *testing.T) {
t.Parallel()
var s Slack
err := s.handleReconnectResponse([]byte(`{"malformedjson}`))
if err == nil {
t.Error("slack handleReconnectResponse(), unmarshalled malformed json")
@@ -280,6 +301,8 @@ func TestHandleReconnectResponse(t *testing.T) {
}
func TestWebsocketSend(t *testing.T) {
t.Parallel()
var s Slack
err := s.WebsocketSend("test", "Hello World!")
if err == nil {
t.Error("slack WebsocketSend(), Sent message through nil websocket")
@@ -287,6 +310,8 @@ func TestWebsocketSend(t *testing.T) {
}
func TestHandleMessage(t *testing.T) {
t.Parallel()
var s Slack
msg := &Message{}
err := s.HandleMessage(msg)
if err == nil {

View File

@@ -7,19 +7,17 @@ import (
"github.com/thrasher-corp/gocryptotrader/config"
)
var s SMSGlobal
func TestSetup(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig("../../testdata/configtest.json", true)
if err != nil {
t.Fatal(err)
}
t.Parallel()
var s SMSGlobal
cfg := &config.Config{Communications: base.CommunicationsConfig{}}
commsCfg := cfg.GetCommunicationsConfig()
s.Setup(&commsCfg)
}
func TestConnect(t *testing.T) {
t.Parallel()
var s SMSGlobal
err := s.Connect()
if err != nil {
t.Error("SMSGlobal Connect() error", err)
@@ -27,6 +25,8 @@ func TestConnect(t *testing.T) {
}
func TestPushEvent(t *testing.T) {
t.Parallel()
var s SMSGlobal
err := s.PushEvent(base.Event{})
if err != nil {
t.Error("SMSGlobal PushEvent() error", err)
@@ -34,6 +34,15 @@ func TestPushEvent(t *testing.T) {
}
func TestGetEnabledContacts(t *testing.T) {
t.Parallel()
s := SMSGlobal{
Contacts: []Contact{
{
Name: "test123",
Enabled: true,
},
},
}
v := s.GetEnabledContacts()
if v != 1 {
t.Error("SMSGlobal GetEnabledContacts() error")
@@ -41,7 +50,17 @@ func TestGetEnabledContacts(t *testing.T) {
}
func TestGetContactByNumber(t *testing.T) {
_, err := s.GetContactByNumber("1231424")
t.Parallel()
s := SMSGlobal{
Contacts: []Contact{
{
Name: "test123",
Enabled: true,
Number: "1337",
},
},
}
_, err := s.GetContactByNumber("1337")
if err != nil {
t.Error("SMSGlobal GetContactByNumber() error", err)
}
@@ -52,7 +71,16 @@ func TestGetContactByNumber(t *testing.T) {
}
func TestGetContactByName(t *testing.T) {
_, err := s.GetContactByName("StyleGherkin")
t.Parallel()
s := SMSGlobal{
Contacts: []Contact{
{
Name: "test123",
Enabled: true,
},
},
}
_, err := s.GetContactByName("test123")
if err != nil {
t.Error("SMSGlobal GetContactByName() error", err)
}
@@ -63,11 +91,15 @@ func TestGetContactByName(t *testing.T) {
}
func TestAddContact(t *testing.T) {
t.Parallel()
s := SMSGlobal{
Contacts: []Contact{},
}
err := s.AddContact(Contact{Name: "bra", Number: "2876", Enabled: true})
if err != nil {
t.Error("SMSGlobal AddContact() error", err)
}
err = s.AddContact(Contact{Name: "StyleGherkin", Number: "1231424", Enabled: true})
err = s.AddContact(Contact{Name: "bra", Number: "2876", Enabled: true})
if err == nil {
t.Error("SMSGlobal AddContact() error")
}
@@ -75,10 +107,23 @@ func TestAddContact(t *testing.T) {
if err == nil {
t.Error("SMSGlobal AddContact() error")
}
if len(s.Contacts) == 0 {
t.Error("failed to add contacts")
}
}
func TestRemoveContact(t *testing.T) {
err := s.RemoveContact(Contact{Name: "StyleGherkin", Number: "1231424", Enabled: true})
t.Parallel()
s := SMSGlobal{
Contacts: []Contact{
{
Name: "test123",
Enabled: true,
Number: "1337",
},
},
}
err := s.RemoveContact(Contact{Name: "test123", Number: "1337", Enabled: true})
if err != nil {
t.Error("SMSGlobal RemoveContact() error", err)
}
@@ -89,6 +134,8 @@ func TestRemoveContact(t *testing.T) {
}
func TestSendMessageToAll(t *testing.T) {
t.Parallel()
var s SMSGlobal
err := s.SendMessageToAll("Hello,World!")
if err != nil {
t.Error("SMSGlobal SendMessageToAll() error", err)
@@ -96,6 +143,8 @@ func TestSendMessageToAll(t *testing.T) {
}
func TestSendMessage(t *testing.T) {
t.Parallel()
var s SMSGlobal
err := s.SendMessage("1337", "Hello!")
if err != nil {
t.Error("SMSGlobal SendMessage() error", err)

View File

@@ -10,11 +10,8 @@ import (
var s SMTPservice
func TestSetup(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig("../../testdata/configtest.json", true)
if err != nil {
t.Fatal(err)
}
t.Parallel()
cfg := &config.Config{Communications: base.CommunicationsConfig{}}
commsCfg := cfg.GetCommunicationsConfig()
s.Setup(&commsCfg)
}

View File

@@ -11,15 +11,18 @@ const (
testErrNotFound = "Not Found"
)
var T Telegram
func TestSetup(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig("../../testdata/configtest.json", true)
if err != nil {
t.Fatal(err)
}
t.Parallel()
cfg := &config.Config{Communications: base.CommunicationsConfig{
TelegramConfig: base.TelegramConfig{
Name: "Telegram",
Enabled: false,
Verbose: false,
VerificationToken: "testest",
},
}}
commsCfg := cfg.GetCommunicationsConfig()
var T Telegram
T.Setup(&commsCfg)
if T.Name != "Telegram" || T.Enabled || T.Token != "testest" || T.Verbose {
t.Error("telegram Setup() error, unexpected setup values",
@@ -31,6 +34,8 @@ func TestSetup(t *testing.T) {
}
func TestConnect(t *testing.T) {
t.Parallel()
var T Telegram
err := T.Connect()
if err == nil {
t.Error("telegram Connect() error")
@@ -38,6 +43,8 @@ func TestConnect(t *testing.T) {
}
func TestPushEvent(t *testing.T) {
t.Parallel()
var T Telegram
err := T.PushEvent(base.Event{})
if err != nil {
t.Error("telegram PushEvent() error", err)
@@ -52,6 +59,7 @@ func TestPushEvent(t *testing.T) {
func TestHandleMessages(t *testing.T) {
t.Parallel()
var T Telegram
chatID := int64(1337)
err := T.HandleMessages(cmdHelp, chatID)
if err.Error() != testErrNotFound {
@@ -82,6 +90,7 @@ func TestHandleMessages(t *testing.T) {
func TestGetUpdates(t *testing.T) {
t.Parallel()
var T Telegram
_, err := T.GetUpdates()
if err != nil {
t.Error("telegram GetUpdates() error", err)
@@ -90,6 +99,7 @@ func TestGetUpdates(t *testing.T) {
func TestTestConnection(t *testing.T) {
t.Parallel()
var T Telegram
err := T.TestConnection()
if err.Error() != testErrNotFound {
t.Errorf("telegram TestConnection() error, expected 'Not found' got '%s'",
@@ -99,6 +109,7 @@ func TestTestConnection(t *testing.T) {
func TestSendMessage(t *testing.T) {
t.Parallel()
var T Telegram
err := T.SendMessage("Test message", int64(1337))
if err.Error() != testErrNotFound {
t.Errorf("telegram SendMessage() error, expected 'Not found' got '%s'",
@@ -108,6 +119,7 @@ func TestSendMessage(t *testing.T) {
func TestSendHTTPRequest(t *testing.T) {
t.Parallel()
var T Telegram
err := T.SendHTTPRequest("0.0.0.0", nil, nil)
if err == nil {
t.Error("telegram SendHTTPRequest() error")

View File

@@ -1062,7 +1062,7 @@ func (c *Config) CheckBankAccountConfig() {
}
}
}
banking.Accounts = c.BankAccounts
banking.SetAccounts(c.BankAccounts...)
}
// CheckCurrencyConfigValues checks to see if the currency config values are correct or not

View File

@@ -38,6 +38,7 @@ func TestPromptForConfigKey(t *testing.T) {
}
func TestEncryptConfigFile(t *testing.T) {
t.Parallel()
_, err := EncryptConfigFile([]byte("test"), nil)
if err == nil {
t.Fatal("Expected error")
@@ -67,6 +68,7 @@ func TestEncryptConfigFile(t *testing.T) {
}
func TestDecryptConfigFile(t *testing.T) {
t.Parallel()
result, err := EncryptConfigFile([]byte("test"), []byte("key"))
if err != nil {
t.Fatal(err)
@@ -135,8 +137,9 @@ func TestMakeNewSessionDK(t *testing.T) {
}
func TestEncryptTwiceReusesSaltButNewCipher(t *testing.T) {
c := &Config{}
c.EncryptConfig = 1
c := &Config{
EncryptConfig: 1,
}
tempDir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatalf("Problem creating temp dir at %s: %s\n", tempDir, err)
@@ -148,8 +151,14 @@ func TestEncryptTwiceReusesSaltButNewCipher(t *testing.T) {
if err != nil {
t.Fatalf("Problem creating temp file at %s: %s\n", tempDir, err)
}
passFile.WriteString("pass\npass\n")
passFile.Close()
_, err = passFile.WriteString("pass\npass\n")
if err != nil {
t.Error(err)
}
err = passFile.Close()
if err != nil {
t.Error(err)
}
// Temporarily replace Stdin with a custom input
oldIn := os.Stdin
@@ -179,7 +188,7 @@ func TestEncryptTwiceReusesSaltButNewCipher(t *testing.T) {
if err != nil {
t.Fatalf("Problem reading file %s: %s\n", enc2, err)
}
// legth of prefix + salt
// length of prefix + salt
l := len(EncryptConfirmString+SaltPrefix) + SaltRandomLength
// Even though prefix, including salt with the random bytes is the same
if !bytes.Equal(data1[:l], data2[:l]) {
@@ -285,6 +294,7 @@ func TestReadConfigWithPrompt(t *testing.T) {
}
func TestReadEncryptedConfigFromReader(t *testing.T) {
t.Parallel()
keyProvider := func() ([]byte, error) { return []byte("pass"), nil }
// Encrypted conf for: `{"name":"test"}` with key `pass`
confBytes := []byte{84, 72, 79, 82, 83, 45, 72, 65, 77, 77, 69, 82, 126, 71, 67, 84, 126, 83, 79, 126, 83, 65, 76, 84, 89, 126, 246, 110, 128, 3, 30, 168, 172, 160, 198, 176, 136, 62, 152, 155, 253, 176, 16, 48, 52, 246, 44, 29, 151, 47, 217, 226, 178, 12, 218, 113, 248, 172, 195, 232, 136, 104, 9, 199, 20, 4, 71, 4, 253, 249}

View File

@@ -1,12 +1,14 @@
package config
import (
"errors"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"time"
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/common/convert"
@@ -22,12 +24,10 @@ import (
)
const (
// Default number of enabled exchanges. Modify this whenever an exchange is
// added or removed
defaultEnabledExchanges = 28
testFakeExchangeName = "Stampbit"
testPair = "BTC-USD"
testString = "test"
testFakeExchangeName = "Stampbit"
testPair = "BTC-USD"
testString = "test"
bfx = "Bitfinex"
)
func TestGetNonExistentDefaultFilePathDoesNotCreateDefaultDir(t *testing.T) {
@@ -42,21 +42,28 @@ func TestGetNonExistentDefaultFilePathDoesNotCreateDefaultDir(t *testing.T) {
}
func TestGetCurrencyConfig(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("GetCurrencyConfig LoadConfig error", err)
t.Parallel()
cfg := &Config{
Currency: CurrencyConfig{
ForeignExchangeUpdateDuration: time.Second,
},
}
cCFG := cfg.GetCurrencyConfig()
if cCFG.ForeignExchangeUpdateDuration != cfg.Currency.ForeignExchangeUpdateDuration {
t.Error("did not retrieve correct currency config")
}
_ = cfg.GetCurrencyConfig()
}
func TestGetClientBankAccounts(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Fatal("GetExchangeBankAccounts LoadConfig error", err)
}
_, err = cfg.GetClientBankAccounts("Kraken", "USD")
t.Parallel()
cfg := &Config{BankAccounts: []banking.Account{
{
SupportedCurrencies: "USD",
SupportedExchanges: "Kraken",
},
}}
_, err := cfg.GetClientBankAccounts("Kraken", "USD")
if err != nil {
t.Error("GetExchangeBankAccounts error", err)
}
@@ -67,12 +74,21 @@ func TestGetClientBankAccounts(t *testing.T) {
}
func TestGetExchangeBankAccounts(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("GetExchangeBankAccounts LoadConfig error", err)
t.Parallel()
cfg := &Config{
Exchanges: []ExchangeConfig{{
Name: bfx,
Enabled: true,
BankAccounts: []banking.Account{
{
SupportedCurrencies: "USD",
SupportedExchanges: bfx,
},
},
}},
}
_, err = cfg.GetExchangeBankAccounts("Bitfinex", "", "USD")
_, err := cfg.GetExchangeBankAccounts(bfx, "", "USD")
if err != nil {
t.Error("GetExchangeBankAccounts error", err)
}
@@ -83,32 +99,61 @@ func TestGetExchangeBankAccounts(t *testing.T) {
}
func TestCheckBankAccountConfig(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("GetExchangeBankAccounts LoadConfig error", err)
t.Parallel()
cfg := &Config{
BankAccounts: []banking.Account{
{
Enabled: true,
},
},
}
cfg.BankAccounts[0].Enabled = true
cfg.CheckBankAccountConfig()
if cfg.BankAccounts[0].Enabled {
t.Error("validation should have changed it to false")
}
cfg.BankAccounts[0] = banking.Account{
Enabled: true,
ID: "1337",
BankName: "1337",
BankAddress: "1337",
BankPostalCode: "1337",
BankPostalCity: "1337",
BankCountry: "1337",
AccountName: "1337",
AccountNumber: "1337",
SWIFTCode: "1337",
IBAN: "1337",
BSBNumber: "1337",
BankCode: 1337,
SupportedCurrencies: "1337",
SupportedExchanges: "1337",
}
cfg.CheckBankAccountConfig()
if !cfg.BankAccounts[0].Enabled {
t.Error("validation should have not have changed result")
}
}
func TestUpdateExchangeBankAccounts(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("UpdateExchangeBankAccounts LoadConfig error", err)
t.Parallel()
cfg := &Config{
Exchanges: []ExchangeConfig{
{
Name: bfx,
Enabled: true,
},
},
}
b := []banking.Account{{Enabled: false}}
err = cfg.UpdateExchangeBankAccounts("Bitfinex", b)
err := cfg.UpdateExchangeBankAccounts(bfx, b)
if err != nil {
t.Error("UpdateExchangeBankAccounts error", err)
}
var count int
for _, exch := range cfg.Exchanges {
if exch.Name == "Bitfinex" {
if !exch.BankAccounts[0].Enabled {
for i := range cfg.Exchanges {
if cfg.Exchanges[i].Name == bfx {
if !cfg.Exchanges[i].BankAccounts[0].Enabled {
count++
}
}
@@ -124,13 +169,17 @@ func TestUpdateExchangeBankAccounts(t *testing.T) {
}
func TestUpdateClientBankAccounts(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("UpdateClientBankAccounts LoadConfig error", err)
t.Parallel()
cfg := &Config{
BankAccounts: []banking.Account{
{
BankName: testString,
AccountNumber: "1337",
},
},
}
b := banking.Account{Enabled: false, BankName: testString, AccountNumber: "0234"}
err = cfg.UpdateClientBankAccounts(&b)
b := banking.Account{Enabled: false, BankName: testString, AccountNumber: "1337"}
err := cfg.UpdateClientBankAccounts(&b)
if err != nil {
t.Error("UpdateClientBankAccounts error", err)
}
@@ -154,18 +203,12 @@ func TestUpdateClientBankAccounts(t *testing.T) {
}
func TestCheckClientBankAccounts(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("CheckClientBankAccounts LoadConfig error", err)
}
cfg.BankAccounts = nil
t.Parallel()
cfg := &Config{}
cfg.CheckClientBankAccounts()
if len(cfg.BankAccounts) == 0 {
t.Error("CheckClientBankAccounts error:", err)
t.Error("expected a placeholder account")
}
cfg.BankAccounts = nil
cfg.BankAccounts = []banking.Account{
{
@@ -288,19 +331,24 @@ func TestPurgeExchangeCredentials(t *testing.T) {
}
func TestGetCommunicationsConfig(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("GetCommunicationsConfig LoadConfig error", err)
t.Parallel()
cfg := &Config{
Communications: base.CommunicationsConfig{
SlackConfig: base.SlackConfig{Name: "hellomoto"},
},
}
cCFG := cfg.GetCommunicationsConfig()
if cCFG.SlackConfig.Name != cfg.Communications.SlackConfig.Name {
t.Error("failed to retrieve config")
}
_ = cfg.GetCommunicationsConfig()
}
func TestUpdateCommunicationsConfig(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("UpdateCommunicationsConfig LoadConfig error", err)
t.Parallel()
cfg := &Config{
Communications: base.CommunicationsConfig{
SlackConfig: base.SlackConfig{Name: "hellomoto"},
},
}
cfg.UpdateCommunicationsConfig(&base.CommunicationsConfig{SlackConfig: base.SlackConfig{Name: testString}})
if cfg.Communications.SlackConfig.Name != testString {
@@ -309,38 +357,40 @@ func TestUpdateCommunicationsConfig(t *testing.T) {
}
func TestGetCryptocurrencyProviderConfig(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("GetCryptocurrencyProviderConfig LoadConfig error", err)
t.Parallel()
cfg := &Config{
Currency: CurrencyConfig{
CryptocurrencyProvider: CryptocurrencyProvider{
Name: "hellomoto",
},
},
}
cCFG := cfg.GetCryptocurrencyProviderConfig()
if cCFG.Name != cfg.Currency.CryptocurrencyProvider.Name {
t.Error("failed to retrieve config")
}
_ = cfg.GetCryptocurrencyProviderConfig()
}
func TestUpdateCryptocurrencyProviderConfig(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("UpdateCryptocurrencyProviderConfig LoadConfig error", err)
t.Parallel()
cfg := &Config{
Currency: CurrencyConfig{
CryptocurrencyProvider: CryptocurrencyProvider{
Name: "hellomoto",
},
},
}
orig := cfg.GetCryptocurrencyProviderConfig()
cfg.UpdateCryptocurrencyProviderConfig(CryptocurrencyProvider{Name: "SERIOUS TESTING PROCEDURE!"})
if cfg.Currency.CryptocurrencyProvider.Name != "SERIOUS TESTING PROCEDURE!" {
t.Error("UpdateCurrencyProviderConfig LoadConfig error")
}
cfg.UpdateCryptocurrencyProviderConfig(orig)
}
func TestCheckCommunicationsConfig(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("CheckCommunicationsConfig LoadConfig error", err)
t.Parallel()
cfg := &Config{
Communications: base.CommunicationsConfig{},
}
cfg.Communications = base.CommunicationsConfig{}
cfg.CheckCommunicationsConfig()
if cfg.Communications.SlackConfig.Name != "Slack" ||
cfg.Communications.SMSGlobalConfig.Name != "SMSGlobal" ||
@@ -354,7 +404,7 @@ func TestCheckCommunicationsConfig(t *testing.T) {
cfg.Communications.SMSGlobalConfig.Name = ""
cfg.CheckCommunicationsConfig()
if cfg.Communications.SMSGlobalConfig.Password != testString {
t.Error("CheckCommunicationsConfig error:", err)
t.Error("incorrect password")
}
cfg.SMS.Contacts = append(cfg.SMS.Contacts, base.SMSContact{
@@ -365,7 +415,7 @@ func TestCheckCommunicationsConfig(t *testing.T) {
cfg.Communications.SMSGlobalConfig.Name = ""
cfg.CheckCommunicationsConfig()
if cfg.Communications.SMSGlobalConfig.Contacts[0].Name != "Bobby" {
t.Error("CheckCommunicationsConfig error:", err)
t.Error("incorrect name")
}
cfg.Communications.SMSGlobalConfig.From = ""
@@ -497,7 +547,6 @@ func TestSupportsExchangeAssetType(t *testing.T) {
func TestSetPairs(t *testing.T) {
t.Parallel()
var c Config
pairs := currency.Pairs{
currency.NewPair(currency.BTC, currency.USD),
@@ -544,7 +593,6 @@ func TestSetPairs(t *testing.T) {
func TestGetCurrencyPairConfig(t *testing.T) {
t.Parallel()
var c Config
_, err := c.GetCurrencyPairConfig("asdfg", asset.Spot)
if err == nil {
@@ -602,7 +650,6 @@ func TestCheckPairConfigFormats(t *testing.T) {
if err := c.CheckPairConfigFormats("non-existent"); err == nil {
t.Error("non-existent exchange should throw an error")
}
// Test nil pair store
c.Exchanges = append(c.Exchanges,
ExchangeConfig{
@@ -851,14 +898,26 @@ func TestCheckPairConsistency(t *testing.T) {
}
func TestSupportsPair(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Errorf(
"TestSupportsPair. LoadConfig Error: %s", err.Error(),
)
t.Parallel()
fmt := &currency.PairFormat{}
cfg := &Config{
Exchanges: []ExchangeConfig{
{
Name: bfx,
Enabled: true,
CurrencyPairs: &currency.PairsManager{
Pairs: map[asset.Item]*currency.PairStore{
asset.Spot: {
AssetEnabled: convert.BoolPtr(true),
Available: []currency.Pair{currency.NewPair(currency.BTC, currency.USD)},
ConfigFormat: fmt,
RequestFormat: fmt,
},
},
},
},
},
}
assetType := asset.Spot
if cfg.SupportsPair("asdf",
currency.NewPair(currency.BTC, currency.USD), assetType) {
@@ -867,10 +926,9 @@ func TestSupportsPair(t *testing.T) {
)
}
if !cfg.SupportsPair("Bitfinex",
currency.NewPair(currency.BTC, currency.USD), assetType) {
if !cfg.SupportsPair(bfx, currency.NewPair(currency.BTC, currency.USD), assetType) {
t.Errorf(
"TestSupportsPair. Incorrect values. Err: %s", err,
"expected true",
)
}
}
@@ -1065,22 +1123,16 @@ func TestGetEnabledPairs(t *testing.T) {
}
func TestGetEnabledExchanges(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Errorf(
"TestGetEnabledExchanges. LoadConfig Error: %s", err.Error(),
)
}
t.Parallel()
cfg := &Config{Exchanges: []ExchangeConfig{
{
Name: bfx,
Enabled: true,
},
}}
exchanges := cfg.GetEnabledExchanges()
if len(exchanges) != defaultEnabledExchanges {
t.Error(
"TestGetEnabledExchanges. Enabled exchanges value mismatch",
)
}
if !common.StringDataCompare(exchanges, "Bitfinex") {
if !common.StringDataCompare(exchanges, bfx) {
t.Error(
"TestGetEnabledExchanges. Expected exchange Bitfinex not found",
)
@@ -1088,14 +1140,13 @@ func TestGetEnabledExchanges(t *testing.T) {
}
func TestGetDisabledExchanges(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Errorf(
"TestGetDisabledExchanges. LoadConfig Error: %s", err.Error(),
)
}
t.Parallel()
cfg := &Config{Exchanges: []ExchangeConfig{
{
Name: bfx,
Enabled: true,
},
}}
exchanges := cfg.GetDisabledExchanges()
if len(exchanges) != 0 {
t.Error(
@@ -1103,7 +1154,7 @@ func TestGetDisabledExchanges(t *testing.T) {
)
}
exchCfg, err := cfg.GetExchangeConfig("Bitfinex")
exchCfg, err := cfg.GetExchangeConfig(bfx)
if err != nil {
t.Errorf(
"TestGetDisabledExchanges. GetExchangeConfig Error: %s", err.Error(),
@@ -1126,26 +1177,27 @@ func TestGetDisabledExchanges(t *testing.T) {
}
func TestCountEnabledExchanges(t *testing.T) {
GetConfigEnabledExchanges := GetConfig()
err := GetConfigEnabledExchanges.LoadConfig(TestFile, true)
if err != nil {
t.Error(
"GetConfigEnabledExchanges load config error: " + err.Error(),
)
}
enabledExch := GetConfigEnabledExchanges.CountEnabledExchanges()
if enabledExch != defaultEnabledExchanges {
t.Errorf("Expected %v, Received %v", defaultEnabledExchanges, enabledExch)
t.Parallel()
cfg := &Config{Exchanges: []ExchangeConfig{
{
Enabled: true,
},
}}
enabledExch := cfg.CountEnabledExchanges()
if enabledExch != 1 {
t.Errorf("Expected %v, Received %v", 1, enabledExch)
}
}
func TestGetCurrencyPairDisplayConfig(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Errorf(
"GetCurrencyPairDisplayConfig. LoadConfig Error: %s", err.Error(),
)
t.Parallel()
cfg := &Config{
Currency: CurrencyConfig{
CurrencyPairFormat: &CurrencyPairFormatConfig{
Delimiter: "-",
Uppercase: true,
},
},
}
settings := cfg.GetCurrencyPairDisplayConfig()
if settings.Delimiter != "-" || !settings.Uppercase {
@@ -1156,42 +1208,50 @@ func TestGetCurrencyPairDisplayConfig(t *testing.T) {
}
func TestGetAllExchangeConfigs(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("GetAllExchangeConfigs. LoadConfig error", err)
t.Parallel()
cfg := &Config{
Exchanges: []ExchangeConfig{
{},
},
}
if len(cfg.GetAllExchangeConfigs()) < 26 {
if len(cfg.GetAllExchangeConfigs()) != 1 {
t.Error("GetAllExchangeConfigs error")
}
}
func TestGetExchangeConfig(t *testing.T) {
GetExchangeConfig := GetConfig()
err := GetExchangeConfig.LoadConfig(TestFile, true)
if err != nil {
t.Errorf(
"GetExchangeConfig.LoadConfig Error: %s", err.Error(),
)
t.Parallel()
cfg := &Config{
Exchanges: []ExchangeConfig{
{
Name: bfx,
},
},
}
_, err = GetExchangeConfig.GetExchangeConfig("Bitfinex")
_, err := cfg.GetExchangeConfig(bfx)
if err != nil {
t.Errorf("GetExchangeConfig.GetExchangeConfig Error: %s",
err.Error())
}
_, err = GetExchangeConfig.GetExchangeConfig("Testy")
if err == nil {
t.Error("GetExchangeConfig.GetExchangeConfig Expected error")
_, err = cfg.GetExchangeConfig("Testy")
if !errors.Is(err, ErrExchangeNotFound) {
t.Errorf("received '%v' expected '%v'", err, ErrExchangeNotFound)
}
}
func TestGetForexProviderConfig(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("GetForexProviderConfig. LoadConfig error", err)
t.Parallel()
fxr := "Fixer"
cfg := &Config{
Currency: CurrencyConfig{
ForexProviders: []currency.FXSettings{
{
Name: fxr,
},
},
},
}
_, err = cfg.GetForexProvider("Fixer")
_, err := cfg.GetForexProvider(fxr)
if err != nil {
t.Error("GetForexProviderConfig error", err)
}
@@ -1203,25 +1263,37 @@ func TestGetForexProviderConfig(t *testing.T) {
}
func TestGetForexProviders(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error(err)
t.Parallel()
fxr := "Fixer"
cfg := &Config{
Currency: CurrencyConfig{
ForexProviders: []currency.FXSettings{
{
Name: fxr,
},
},
},
}
if r := cfg.GetForexProviders(); len(r) != 6 {
if r := cfg.GetForexProviders(); len(r) != 1 {
t.Error("unexpected length of forex providers")
}
}
func TestGetPrimaryForexProvider(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("GetPrimaryForexProvider. LoadConfig error", err)
t.Parallel()
fxr := "Fixer"
cfg := &Config{
Currency: CurrencyConfig{
ForexProviders: []currency.FXSettings{
{
Name: fxr,
PrimaryProvider: true,
},
},
},
}
primary := cfg.GetPrimaryForexProvider()
if primary == "" {
if primary != fxr {
t.Error("GetPrimaryForexProvider error")
}
@@ -1235,25 +1307,29 @@ func TestGetPrimaryForexProvider(t *testing.T) {
}
func TestUpdateExchangeConfig(t *testing.T) {
c := GetConfig()
err := c.LoadConfig(TestFile, true)
if err != nil {
t.Error(err)
t.Parallel()
ok := "OKEX"
cfg := &Config{
Exchanges: []ExchangeConfig{
{
Name: ok,
API: APIConfig{Credentials: APICredentialsConfig{}},
},
},
}
e := &ExchangeConfig{}
err = c.UpdateExchangeConfig(e)
err := cfg.UpdateExchangeConfig(e)
if err == nil {
t.Error("Expected error from non-existent exchange")
}
e, err = c.GetExchangeConfig("OKEX")
e, err = cfg.GetExchangeConfig(ok)
if err != nil {
t.Error(err)
}
e.API.Credentials.Key = "test1234"
err = c.UpdateExchangeConfig(e)
err = cfg.UpdateExchangeConfig(e)
if err != nil {
t.Error(err)
}
@@ -1481,7 +1557,10 @@ func TestCheckExchangeConfigValues(t *testing.T) {
cfg.Exchanges[0].API.Credentials.Secret = "Secret"
cfg.Exchanges[0].API.AuthenticatedSupport = true
cfg.Exchanges[0].API.AuthenticatedWebsocketSupport = true
cfg.CheckExchangeConfigValues()
err = cfg.CheckExchangeConfigValues()
if err != nil {
t.Error(err)
}
if cfg.Exchanges[0].API.AuthenticatedSupport ||
cfg.Exchanges[0].API.AuthenticatedWebsocketSupport {
t.Error("Expected authenticated endpoints to be false from invalid API keys")
@@ -1493,7 +1572,10 @@ func TestCheckExchangeConfigValues(t *testing.T) {
cfg.Exchanges[0].API.AuthenticatedWebsocketSupport = true
cfg.Exchanges[0].API.Credentials.ClientID = DefaultAPIClientID
cfg.Exchanges[0].API.Credentials.Secret = "TESTYTEST"
cfg.CheckExchangeConfigValues()
err = cfg.CheckExchangeConfigValues()
if err != nil {
t.Error(err)
}
if cfg.Exchanges[0].API.AuthenticatedSupport ||
cfg.Exchanges[0].API.AuthenticatedWebsocketSupport {
t.Error("Expected AuthenticatedAPISupport to be false from invalid API keys")
@@ -1505,7 +1587,10 @@ func TestCheckExchangeConfigValues(t *testing.T) {
cfg.Exchanges[0].API.Credentials.Key = "meow"
cfg.Exchanges[0].API.Credentials.Secret = "test123"
cfg.Exchanges[0].API.Credentials.ClientID = "clientIDerino"
cfg.CheckExchangeConfigValues()
err = cfg.CheckExchangeConfigValues()
if err != nil {
t.Error(err)
}
if !cfg.Exchanges[0].API.AuthenticatedSupport ||
!cfg.Exchanges[0].API.AuthenticatedWebsocketSupport {
t.Error("Expected AuthenticatedAPISupport and AuthenticatedWebsocketAPISupport to be false from invalid API keys")
@@ -1517,7 +1602,10 @@ func TestCheckExchangeConfigValues(t *testing.T) {
// Test empty exchange name for an enabled exchange
cfg.Exchanges[0].Enabled = true
cfg.Exchanges[0].Name = ""
cfg.CheckExchangeConfigValues()
err = cfg.CheckExchangeConfigValues()
if err != nil {
t.Error(err)
}
if cfg.Exchanges[0].Enabled {
t.Errorf(
"Exchange with no name should be empty",
@@ -1610,14 +1698,35 @@ func TestCheckExchangeConfigValues(t *testing.T) {
}
func TestRetrieveConfigCurrencyPairs(t *testing.T) {
cfg := GetConfig()
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Errorf(
"TestRetrieveConfigCurrencyPairs.LoadConfig: %s", err.Error(),
)
t.Parallel()
cp1 := currency.NewPair(currency.DOGE, currency.XRP)
cp2 := currency.NewPair(currency.DOGE, currency.USD)
cfg := &Config{
Exchanges: []ExchangeConfig{
{
Enabled: true,
BaseCurrencies: currency.Currencies{
currency.USD,
},
CurrencyPairs: &currency.PairsManager{
RequestFormat: nil,
ConfigFormat: nil,
UseGlobalFormat: false,
LastUpdated: 0,
Pairs: map[asset.Item]*currency.PairStore{
asset.Spot: {
AssetEnabled: convert.BoolPtr(true),
Available: currency.Pairs{cp1, cp2},
Enabled: currency.Pairs{cp1},
ConfigFormat: &currency.PairFormat{},
RequestFormat: &currency.PairFormat{},
},
},
},
},
},
}
err = cfg.RetrieveConfigCurrencyPairs(true, asset.Spot)
err := cfg.RetrieveConfigCurrencyPairs(true, asset.Spot)
if err != nil {
t.Errorf(
"TestRetrieveConfigCurrencyPairs.RetrieveConfigCurrencyPairs: %s",
@@ -1635,19 +1744,20 @@ func TestRetrieveConfigCurrencyPairs(t *testing.T) {
}
func TestReadConfigFromFile(t *testing.T) {
readConfig := GetConfig()
err := readConfig.ReadConfigFromFile(TestFile, true)
cfg := &Config{}
err := cfg.ReadConfigFromFile(TestFile, true)
if err != nil {
t.Errorf("TestReadConfig %s", err.Error())
}
err = readConfig.ReadConfigFromFile("bla", true)
err = cfg.ReadConfigFromFile("bla", true)
if err == nil {
t.Error("TestReadConfig error cannot be nil")
}
}
func TestReadConfigFromReader(t *testing.T) {
t.Parallel()
confString := `{"name":"test"}`
conf, encrypted, err := ReadConfig(strings.NewReader(confString), Unencrypted)
if err != nil {
@@ -1667,21 +1777,21 @@ func TestReadConfigFromReader(t *testing.T) {
}
func TestLoadConfig(t *testing.T) {
loadConfig := GetConfig()
err := loadConfig.LoadConfig(TestFile, true)
cfg := &Config{}
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Error("TestLoadConfig " + err.Error())
}
err = loadConfig.LoadConfig("testy", true)
err = cfg.LoadConfig("testy", true)
if err == nil {
t.Error("TestLoadConfig Expected error")
}
}
func TestSaveConfigToFile(t *testing.T) {
saveConfig := GetConfig()
err := saveConfig.LoadConfig(TestFile, true)
cfg := &Config{}
err := cfg.LoadConfig(TestFile, true)
if err != nil {
t.Errorf("TestSaveConfig.LoadConfig: %s", err.Error())
}
@@ -1691,7 +1801,7 @@ func TestSaveConfigToFile(t *testing.T) {
}
f.Close()
defer os.Remove(f.Name())
err2 := saveConfig.SaveConfigToFile(f.Name())
err2 := cfg.SaveConfigToFile(f.Name())
if err2 != nil {
t.Errorf("TestSaveConfig.SaveConfig, %s", err2.Error())
}
@@ -1722,6 +1832,7 @@ func TestDefaultFilePath(t *testing.T) {
// means moving a users config file around), a way of getting around this is
// to pass the datadir as a param line but adds a burden to everyone who
// uses it
t.Parallel()
result := DefaultFilePath()
if !strings.Contains(result, File) &&
!strings.Contains(result, EncryptedFile) {
@@ -1730,6 +1841,7 @@ func TestDefaultFilePath(t *testing.T) {
}
func TestGetFilePath(t *testing.T) {
t.Parallel()
expected := "blah.json"
result, wasDefault, _ := GetFilePath("blah.json")
if result != "blah.json" {
@@ -1792,13 +1904,36 @@ func TestCheckRemoteControlConfig(t *testing.T) {
}
func TestCheckConfig(t *testing.T) {
var c Config
err := c.LoadConfig(TestFile, true)
if err != nil {
t.Errorf("%s", err)
t.Parallel()
cp1 := currency.NewPair(currency.DOGE, currency.XRP)
cp2 := currency.NewPair(currency.DOGE, currency.USD)
cfg := &Config{
Exchanges: []ExchangeConfig{
{
Name: testFakeExchangeName,
Enabled: true,
BaseCurrencies: currency.Currencies{
currency.USD,
},
CurrencyPairs: &currency.PairsManager{
RequestFormat: nil,
ConfigFormat: nil,
UseGlobalFormat: false,
LastUpdated: 0,
Pairs: map[asset.Item]*currency.PairStore{
asset.Spot: {
AssetEnabled: convert.BoolPtr(true),
Available: currency.Pairs{cp1, cp2},
Enabled: currency.Pairs{cp1},
ConfigFormat: &currency.PairFormat{},
RequestFormat: &currency.PairFormat{},
},
},
},
},
},
}
err = c.CheckConfig()
err := cfg.CheckConfig()
if err != nil {
t.Fatal(err)
}
@@ -1952,92 +2087,94 @@ func TestCheckDatabaseConfig(t *testing.T) {
}
func TestCheckNTPConfig(t *testing.T) {
c := GetConfig()
t.Parallel()
cfg := &Config{
NTPClient: NTPClientConfig{},
}
c.NTPClient.Level = 0
c.NTPClient.Pool = nil
c.NTPClient.AllowedNegativeDifference = nil
c.NTPClient.AllowedDifference = nil
cfg.CheckNTPConfig()
c.CheckNTPConfig()
if c.NTPClient.Pool[0] != "pool.ntp.org:123" {
if cfg.NTPClient.Pool[0] != "pool.ntp.org:123" {
t.Error("ntpclient with no valid pool should default to pool.ntp.org")
}
if c.NTPClient.AllowedDifference == nil {
if cfg.NTPClient.AllowedDifference == nil {
t.Error("ntpclient with nil alloweddifference should default to sane value")
}
if c.NTPClient.AllowedNegativeDifference == nil {
if cfg.NTPClient.AllowedNegativeDifference == nil {
t.Error("ntpclient with nil allowednegativedifference should default to sane value")
}
}
func TestCheckCurrencyConfigValues(t *testing.T) {
c := GetConfig()
c.Currency.ForexProviders = nil
c.Currency.CryptocurrencyProvider = CryptocurrencyProvider{}
err := c.CheckCurrencyConfigValues()
t.Parallel()
cfg := &Config{
Currency: CurrencyConfig{},
}
cfg.Currency.ForexProviders = nil
cfg.Currency.CryptocurrencyProvider = CryptocurrencyProvider{}
err := cfg.CheckCurrencyConfigValues()
if err != nil {
t.Error(err)
}
if c.Currency.ForexProviders == nil {
if cfg.Currency.ForexProviders == nil {
t.Error("Failed to populate c.Currency.ForexProviders")
}
if c.Currency.CryptocurrencyProvider.APIkey != DefaultUnsetAPIKey {
if cfg.Currency.CryptocurrencyProvider.APIkey != DefaultUnsetAPIKey {
t.Error("Failed to set the api key to the default key")
}
if c.Currency.CryptocurrencyProvider.Name != "CoinMarketCap" {
if cfg.Currency.CryptocurrencyProvider.Name != "CoinMarketCap" {
t.Error("Failed to set the c.Currency.CryptocurrencyProvider.Name")
}
c.Currency.ForexProviders[0].Enabled = true
c.Currency.ForexProviders[0].Name = "CurrencyConverter"
c.Currency.ForexProviders[0].PrimaryProvider = true
c.Currency.Cryptocurrencies = nil
c.Cryptocurrencies = nil
c.Currency.CurrencyPairFormat = nil
c.CurrencyPairFormat = &CurrencyPairFormatConfig{
cfg.Currency.ForexProviders[0].Enabled = true
cfg.Currency.ForexProviders[0].Name = "CurrencyConverter"
cfg.Currency.ForexProviders[0].PrimaryProvider = true
cfg.Currency.Cryptocurrencies = nil
cfg.Cryptocurrencies = nil
cfg.Currency.CurrencyPairFormat = nil
cfg.CurrencyPairFormat = &CurrencyPairFormatConfig{
Uppercase: true,
}
c.Currency.FiatDisplayCurrency = currency.Code{}
c.FiatDisplayCurrency = &currency.BTC
c.Currency.CryptocurrencyProvider.Enabled = true
err = c.CheckCurrencyConfigValues()
cfg.Currency.FiatDisplayCurrency = currency.Code{}
cfg.FiatDisplayCurrency = &currency.BTC
cfg.Currency.CryptocurrencyProvider.Enabled = true
err = cfg.CheckCurrencyConfigValues()
if err != nil {
t.Error(err)
}
if c.Currency.ForexProviders[0].Enabled {
if cfg.Currency.ForexProviders[0].Enabled {
t.Error("Failed to disable invalid forex provider")
}
if !c.Currency.CurrencyPairFormat.Uppercase {
if !cfg.Currency.CurrencyPairFormat.Uppercase {
t.Error("Failed to apply c.CurrencyPairFormat format to c.Currency.CurrencyPairFormat")
}
c.Currency.CryptocurrencyProvider.Enabled = false
c.Currency.CryptocurrencyProvider.APIkey = ""
c.Currency.CryptocurrencyProvider.AccountPlan = ""
c.FiatDisplayCurrency = &currency.BTC
c.Currency.ForexProviders[0].Enabled = true
c.Currency.ForexProviders[0].Name = "Name"
c.Currency.ForexProviders[0].PrimaryProvider = true
c.Currency.Cryptocurrencies = currency.Currencies{}
c.Cryptocurrencies = &currency.Currencies{}
err = c.CheckCurrencyConfigValues()
cfg.Currency.CryptocurrencyProvider.Enabled = false
cfg.Currency.CryptocurrencyProvider.APIkey = ""
cfg.Currency.CryptocurrencyProvider.AccountPlan = ""
cfg.FiatDisplayCurrency = &currency.BTC
cfg.Currency.ForexProviders[0].Enabled = true
cfg.Currency.ForexProviders[0].Name = "Name"
cfg.Currency.ForexProviders[0].PrimaryProvider = true
cfg.Currency.Cryptocurrencies = currency.Currencies{}
cfg.Cryptocurrencies = &currency.Currencies{}
err = cfg.CheckCurrencyConfigValues()
if err != nil {
t.Error(err)
}
if c.FiatDisplayCurrency != nil {
if cfg.FiatDisplayCurrency != nil {
t.Error("Failed to clear c.FiatDisplayCurrency")
}
if c.Currency.CryptocurrencyProvider.APIkey != DefaultUnsetAPIKey ||
c.Currency.CryptocurrencyProvider.AccountPlan != DefaultUnsetAccountPlan {
if cfg.Currency.CryptocurrencyProvider.APIkey != DefaultUnsetAPIKey ||
cfg.Currency.CryptocurrencyProvider.AccountPlan != DefaultUnsetAccountPlan {
t.Error("Failed to set CryptocurrencyProvider.APIkey and AccountPlan")
}
}
func TestPreengineConfigUpgrade(t *testing.T) {
t.Parallel()
var c Config
if err := c.LoadConfig("../testdata/preengine_config.json", false); err != nil {
t.Fatal(err)

View File

@@ -13,7 +13,7 @@ func (i *Instance) SetConfig(cfg *Config) error {
return ErrNilInstance
}
if cfg == nil {
return errNilConfig
return ErrNilConfig
}
i.m.Lock()
i.config = cfg

View File

@@ -20,8 +20,8 @@ func TestSetConfig(t *testing.T) {
}
err = inst.SetConfig(nil)
if !errors.Is(err, errNilConfig) {
t.Errorf("received %v, expected %v", err, errNilConfig)
if !errors.Is(err, ErrNilConfig) {
t.Errorf("received %v, expected %v", err, ErrNilConfig)
}
inst = nil

View File

@@ -46,9 +46,10 @@ var (
DefaultSQLiteDatabase = "gocryptotrader.db"
// ErrNilInstance for when a database is nil
ErrNilInstance = errors.New("database instance is nil")
errNilConfig = errors.New("received nil config")
errNilSQL = errors.New("database SQL connection is nil")
errFailedPing = errors.New("unable to verify database is connected, failed ping")
// ErrNilConfig for when a config is nil
ErrNilConfig = errors.New("received nil config")
errNilSQL = errors.New("database SQL connection is nil")
errFailedPing = errors.New("unable to verify database is connected, failed ping")
)
const (

View File

@@ -11,6 +11,12 @@ import (
// Connect opens a connection to Postgres database and returns a pointer to database.DB
func Connect(cfg *database.Config) (*database.Instance, error) {
if cfg == nil {
return nil, database.ErrNilConfig
}
if !cfg.Enabled {
return nil, database.ErrDatabaseSupportDisabled
}
if cfg.SSLMode == "" {
cfg.SSLMode = "disable"
}

View File

@@ -83,16 +83,13 @@ func TestAudit(t *testing.T) {
if !testhelpers.CheckValidConfig(&test.config.ConnectionDetails) {
t.Skip("database not configured skipping test")
}
dbConn, err := testhelpers.ConnectToDatabase(test.config)
if err != nil {
t.Fatal(err)
}
if test.runner != nil {
test.runner(t)
}
if test.closer != nil {
err = test.closer(dbConn)
if err != nil {

View File

@@ -124,8 +124,8 @@ func TestDataHistoryJob(t *testing.T) {
Asset: asset.Spot.String(),
Base: currency.BTC.String(),
Quote: currency.USD.String(),
StartDate: time.Now().Add(time.Duration(i) * time.Second),
EndDate: time.Now().Add(time.Minute * time.Duration(i)),
StartDate: time.Now().Add(time.Duration(i+1) * time.Second).UTC(),
EndDate: time.Now().Add(time.Minute * time.Duration(i+1)).UTC(),
Interval: int64(i),
})
}
@@ -144,8 +144,8 @@ func TestDataHistoryJob(t *testing.T) {
Asset: asset.Spot.String(),
Base: currency.BTC.String(),
Quote: currency.USD.String(),
StartDate: time.Now().Add(time.Duration(i) * time.Second),
EndDate: time.Now().Add(time.Minute * time.Duration(i)),
StartDate: time.Now().Add(time.Duration(i+1) * time.Second).UTC(),
EndDate: time.Now().Add(time.Minute * time.Duration(i+1)).UTC(),
Interval: int64(i),
}
if i == 19 {
@@ -179,7 +179,7 @@ func TestDataHistoryJob(t *testing.T) {
t.Errorf("expected 19, received %v", len(results))
}
jerb, err := db.getJobAndAllResultsPostgres(jerberoos[0].Nickname)
jerb, err := db.GetJobAndAllResults(jerberoos[0].Nickname)
if err != nil {
t.Fatal(err)
}

View File

@@ -107,7 +107,7 @@ func verifyTradeInIntervalsSqlite(ctx context.Context, tx *sql.Tx, exchangeName,
quote,
irh.Ranges[i].Intervals[j].Start.Time.UTC().Format(time.RFC3339),
irh.Ranges[i].Intervals[j].End.Time.UTC().Format(time.RFC3339))).One(ctx, tx)
if err != nil {
if err != nil && err != sql.ErrNoRows {
return err
}
if result != nil {
@@ -126,14 +126,14 @@ func verifyTradeInIntervalsPostgres(ctx context.Context, tx *sql.Tx, exchangeNam
}
for i := range irh.Ranges {
for j := range irh.Ranges[i].Intervals {
result, err := postgres.Trades(qm.Where("exchange_name_id = ? AND asset = ? AND base = ? AND quote = ? timestamp between ? AND ?",
result, err := postgres.Trades(qm.Where("exchange_name_id = ? AND asset = ? AND base = ? AND quote = ? AND timestamp between ? AND ?",
exch.ID,
assetType,
base,
quote,
irh.Ranges[i].Intervals[j].Start.Time.UTC().Format(time.RFC3339),
irh.Ranges[i].Intervals[j].End.Time.UTC().Format(time.RFC3339))).One(ctx, tx)
if err != nil {
irh.Ranges[i].Intervals[j].Start.Time.UTC(),
irh.Ranges[i].Intervals[j].End.Time.UTC())).One(ctx, tx)
if err != nil && err != sql.ErrNoRows {
return err
}
if result != nil {

View File

@@ -103,7 +103,7 @@ func tradeSQLTester(t *testing.T) {
uu, _ := uuid.NewV4()
trades = append(trades, Data{
ID: uu.String(),
Timestamp: firstTime.Add(time.Minute * time.Duration(i)),
Timestamp: firstTime.Add(time.Minute * time.Duration(i+1)),
Exchange: testExchanges[0].Name,
Base: currency.BTC.String(),
Quote: currency.USD.String(),
@@ -123,7 +123,7 @@ func tradeSQLTester(t *testing.T) {
uu, _ := uuid.NewV4()
trades2 = append(trades2, Data{
ID: uu.String(),
Timestamp: firstTime.Add(time.Minute * time.Duration(i)),
Timestamp: firstTime.Add(time.Minute * time.Duration(i+1)),
Exchange: testExchanges[0].Name,
Base: currency.BTC.String(),
Quote: currency.USD.String(),
@@ -171,7 +171,6 @@ func tradeSQLTester(t *testing.T) {
if err != nil {
t.Error(err)
}
err = VerifyTradeInIntervals(testExchanges[0].Name,
asset.Spot.String(),
currency.BTC.String(),
@@ -181,15 +180,10 @@ func tradeSQLTester(t *testing.T) {
t.Error(err)
}
if !ranges.HasDataAtDate(firstTime) {
t.Error("expected data")
}
err = DeleteTrades(trades...)
if err != nil {
t.Error(err)
}
err = DeleteTrades(trades2...)
if err != nil {
t.Error(err)

View File

@@ -8,9 +8,7 @@ import (
"net/http/httptest"
"os"
"reflect"
"sync"
"testing"
"time"
"github.com/thrasher-corp/gocryptotrader/config"
)
@@ -61,15 +59,10 @@ func TestStartRESTServer(t *testing.T) {
t.Errorf("error '%v', expected '%v'", err, errServerDisabled)
}
m.remoteConfig.DeprecatedRPC.Enabled = true
var wg sync.WaitGroup
wg.Add(1)
// this is difficult to test as a webserver actually starts, so quit if an immediate error is not received
err = m.StartRESTServer()
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Second)
wg.Done()
}
func TestStartWebsocketServer(t *testing.T) {

View File

@@ -3,7 +3,6 @@ package engine
import (
"errors"
"testing"
"time"
"github.com/thrasher-corp/gocryptotrader/communications"
"github.com/thrasher-corp/gocryptotrader/communications/base"
@@ -151,7 +150,6 @@ func TestPushEvent(t *testing.T) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
m.PushEvent(base.Event{})
time.Sleep(time.Second)
m.PushEvent(base.Event{})
m = nil
m.PushEvent(base.Event{})

View File

@@ -1,7 +1,6 @@
package engine
import (
"errors"
"fmt"
"sync"
"sync/atomic"
@@ -16,19 +15,11 @@ import (
// DatabaseConnectionManagerName is an exported subsystem name
const DatabaseConnectionManagerName = "database"
var errDatabaseDisabled = errors.New("database support disabled")
// DatabaseConnectionManager holds the database connection and its status
type DatabaseConnectionManager struct {
started int32
shutdown chan struct{}
enabled bool
verbose bool
host string
username string
password string
database string
driver string
cfg database.Config
wg sync.WaitGroup
dbConn *database.Instance
}
@@ -57,13 +48,7 @@ func SetupDatabaseConnectionManager(cfg *database.Config) (*DatabaseConnectionMa
}
m := &DatabaseConnectionManager{
shutdown: make(chan struct{}),
enabled: cfg.Enabled,
verbose: cfg.Verbose,
host: cfg.Host,
username: cfg.Username,
password: cfg.Password,
database: cfg.Database,
driver: cfg.Driver,
cfg: *cfg,
dbConn: database.DB,
}
err := m.dbConn.SetConfig(cfg)
@@ -98,23 +83,23 @@ func (m *DatabaseConnectionManager) Start(wg *sync.WaitGroup) (err error) {
log.Debugln(log.DatabaseMgr, "Database manager starting...")
if m.enabled {
if m.cfg.Enabled {
m.shutdown = make(chan struct{})
switch m.driver {
switch m.cfg.Driver {
case database.DBPostgreSQL:
log.Debugf(log.DatabaseMgr,
"Attempting to establish database connection to host %s/%s utilising %s driver\n",
m.host,
m.database,
m.driver)
m.dbConn, err = dbpsql.Connect(m.dbConn.GetConfig())
m.cfg.Host,
m.cfg.Database,
m.cfg.Driver)
m.dbConn, err = dbpsql.Connect(&m.cfg)
case database.DBSQLite,
database.DBSQLite3:
log.Debugf(log.DatabaseMgr,
"Attempting to establish database connection to %s utilising %s driver\n",
m.database,
m.driver)
m.dbConn, err = dbsqlite3.Connect(m.database)
m.cfg.Database,
m.cfg.Driver)
m.dbConn, err = dbsqlite3.Connect(m.cfg.Database)
default:
return database.ErrNoDatabaseProvided
}
@@ -128,7 +113,7 @@ func (m *DatabaseConnectionManager) Start(wg *sync.WaitGroup) (err error) {
return nil
}
return errDatabaseDisabled
return database.ErrDatabaseSupportDisabled
}
// Stop stops the database manager and closes the connection
@@ -185,7 +170,7 @@ func (m *DatabaseConnectionManager) checkConnection() error {
if atomic.LoadInt32(&m.started) == 0 {
return fmt.Errorf("%s %w", DatabaseConnectionManagerName, ErrSubSystemNotStarted)
}
if !m.enabled {
if !m.cfg.Enabled {
return database.ErrDatabaseSupportDisabled
}
if m.dbConn == nil {

View File

@@ -60,8 +60,8 @@ func TestStartSQLite(t *testing.T) {
}
var wg sync.WaitGroup
err = m.Start(&wg)
if !errors.Is(err, errDatabaseDisabled) {
t.Errorf("error '%v', expected '%v'", err, errDatabaseDisabled)
if !errors.Is(err, database.ErrDatabaseSupportDisabled) {
t.Errorf("error '%v', expected '%v'", err, database.ErrDatabaseSupportDisabled)
}
m, err = SetupDatabaseConnectionManager(&database.Config{Enabled: true})
if !errors.Is(err, nil) {
@@ -71,10 +71,10 @@ func TestStartSQLite(t *testing.T) {
if !errors.Is(err, database.ErrNoDatabaseProvided) {
t.Errorf("error '%v', expected '%v'", err, database.ErrNoDatabaseProvided)
}
m.driver = database.DBSQLite
m.cfg = database.Config{Driver: database.DBSQLite}
err = m.Start(&wg)
if !errors.Is(err, database.ErrFailedToConnect) {
t.Errorf("error '%v', expected '%v'", err, database.ErrFailedToConnect)
if !errors.Is(err, database.ErrDatabaseSupportDisabled) {
t.Errorf("error '%v', expected '%v'", err, database.ErrDatabaseSupportDisabled)
}
_, err = SetupDatabaseConnectionManager(&database.Config{
Enabled: true,
@@ -91,23 +91,21 @@ func TestStartSQLite(t *testing.T) {
// This test does not care for a successful connection
func TestStartPostgres(t *testing.T) {
tmpDir := CreateDatabase(t)
defer Cleanup(tmpDir)
m, err := SetupDatabaseConnectionManager(&database.Config{})
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
var wg sync.WaitGroup
err = m.Start(&wg)
if !errors.Is(err, errDatabaseDisabled) {
t.Errorf("error '%v', expected '%v'", err, errDatabaseDisabled)
if !errors.Is(err, database.ErrDatabaseSupportDisabled) {
t.Errorf("error '%v', expected '%v'", err, database.ErrDatabaseSupportDisabled)
}
m.enabled = true
m.cfg.Enabled = true
err = m.Start(&wg)
if !errors.Is(err, database.ErrNoDatabaseProvided) {
t.Errorf("error '%v', expected '%v'", err, database.ErrNoDatabaseProvided)
}
m.driver = database.DBPostgreSQL
m.cfg.Driver = database.DBPostgreSQL
err = m.Start(&wg)
if !errors.Is(err, database.ErrFailedToConnect) {
t.Errorf("error '%v', expected '%v'", err, database.ErrFailedToConnect)

View File

@@ -181,7 +181,7 @@ func (m *DataHistoryManager) compareJobsToData(jobs ...*DataHistoryJob) error {
jobs[i].rangeHolder.SetHasDataFromCandles(candles.Candles)
case dataHistoryTradeDataType:
err := m.tradeLoader(jobs[i].Exchange, jobs[i].Asset.String(), jobs[i].Pair.Base.String(), jobs[i].Pair.Quote.String(), jobs[i].rangeHolder)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
if err != nil && err != sql.ErrNoRows {
return fmt.Errorf("%s could not load trade data: %w", jobs[i].Nickname, err)
}
default:
@@ -682,7 +682,7 @@ func (m *DataHistoryManager) GetByNickname(nickname string, fullDetails bool) (*
// now try the database
j, err := m.jobDB.GetByNickName(nickname)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
if err == sql.ErrNoRows {
// no need to display normal sql err to user
return nil, errJobNotFound
}

View File

@@ -812,7 +812,7 @@ func createDHM(t *testing.T) *DataHistoryManager {
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
t.Fatalf("error '%v', expected '%v'", err, nil)
}
cp := currency.NewPair(currency.BTC, currency.USD)
exch.SetDefaults()
@@ -826,7 +826,7 @@ func createDHM(t *testing.T) *DataHistoryManager {
exch2, err := em.NewExchangeByName("Binance")
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
t.Fatalf("error '%v', expected '%v'", err, nil)
}
cp2 := currency.NewPair(currency.BTC, currency.USDT)
exch2.SetDefaults()

View File

@@ -5,6 +5,7 @@ import (
"io/ioutil"
"os"
"testing"
"time"
"github.com/thrasher-corp/gocryptotrader/config"
)
@@ -165,8 +166,15 @@ func TestStartStopTwoDoesNotCausePanic(t *testing.T) {
}
func TestCheckExchangeExists(t *testing.T) {
e := CreateTestBot(t)
t.Parallel()
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if !errors.Is(err, nil) {
t.Fatalf("received '%v' expected '%v'", err, nil)
}
exch.SetDefaults()
em.Add(exch)
e := &Engine{ExchangeManager: em}
if e.GetExchangeByName(testExchange) == nil {
t.Errorf("TestGetExchangeExists: Unable to find exchange")
}
@@ -177,12 +185,16 @@ func TestCheckExchangeExists(t *testing.T) {
}
func TestGetExchangeByName(t *testing.T) {
e := CreateTestBot(t)
exch := e.GetExchangeByName(testExchange)
if exch == nil {
t.Errorf("TestGetExchangeByName: Failed to get exchange")
t.Parallel()
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if !errors.Is(err, nil) {
t.Fatalf("received '%v' expected '%v'", err, nil)
}
exch.SetDefaults()
exch.SetEnabled(true)
em.Add(exch)
e := &Engine{ExchangeManager: em}
if !exch.IsEnabled() {
t.Errorf("TestGetExchangeByName: Unexpected result")
@@ -205,9 +217,19 @@ func TestGetExchangeByName(t *testing.T) {
}
func TestUnloadExchange(t *testing.T) {
e := CreateTestBot(t)
err := e.UnloadExchange("asdf")
t.Parallel()
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if !errors.Is(err, nil) {
t.Fatalf("received '%v' expected '%v'", err, nil)
}
exch.SetDefaults()
exch.SetEnabled(true)
em.Add(exch)
e := &Engine{ExchangeManager: em,
Config: &config.Config{Exchanges: []config.ExchangeConfig{{Name: testExchange}}},
}
err = e.UnloadExchange("asdf")
if !errors.Is(err, config.ErrExchangeNotFound) {
t.Errorf("error '%v', expected '%v'", err, config.ErrExchangeNotFound)
}
@@ -225,30 +247,29 @@ func TestUnloadExchange(t *testing.T) {
}
func TestDryRunParamInteraction(t *testing.T) {
bot := CreateTestBot(t)
// Simulate overiding default settings and ensure that enabling exchange
// verbose mode will be set on Bitfinex
var err error
if err = bot.UnloadExchange(testExchange); err != nil {
t.Parallel()
bot := &Engine{
ExchangeManager: SetupExchangeManager(),
Settings: Settings{},
Config: &config.Config{
Exchanges: []config.ExchangeConfig{
{
Name: testExchange,
WebsocketTrafficTimeout: time.Second,
},
},
},
}
if err := bot.LoadExchange(testExchange, false, nil); err != nil {
t.Error(err)
}
bot.Settings.CheckParamInteraction = false
bot.Settings.EnableExchangeVerbose = false
if err = bot.LoadExchange(testExchange, false, nil); err != nil {
t.Error(err)
}
exchCfg, err := bot.Config.GetExchangeConfig(testExchange)
if err != nil {
t.Error(err)
}
if exchCfg.Verbose {
t.Error("verbose should have been disabled")
}
if err = bot.UnloadExchange(testExchange); err != nil {
t.Error(err)
}
@@ -267,7 +288,6 @@ func TestDryRunParamInteraction(t *testing.T) {
if err != nil {
t.Error(err)
}
if !bot.Settings.EnableDryRun ||
!exchCfg.Verbose {
t.Error("dryrun should be true and verbose should be true")

View File

@@ -125,7 +125,7 @@ func TestEventManagerAdd(t *testing.T) {
}
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Error(err)
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
@@ -181,7 +181,7 @@ func TestEventManagerRemove(t *testing.T) {
}
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Error(err)
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
@@ -222,7 +222,7 @@ func TestGetEventCounter(t *testing.T) {
}
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Error(err)
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)
@@ -268,7 +268,7 @@ func TestCheckEventCondition(t *testing.T) {
}
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Error(err)
t.Fatal(err)
}
exch.SetDefaults()
em.Add(exch)

View File

@@ -69,7 +69,7 @@ func TestNewExchangeByName(t *testing.T) {
for i := range exchanges {
exch, err := m.NewExchangeByName(exchanges[i])
if err != nil && exchanges[i] != "fake" {
t.Error(err)
t.Fatal(err)
}
if err == nil {
exch.SetDefaults()

View File

@@ -16,6 +16,7 @@ import (
"time"
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/common/convert"
"github.com/thrasher-corp/gocryptotrader/common/file"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/currency"
@@ -29,34 +30,73 @@ import (
var testExchange = "Bitstamp"
func CreateTestBot(t *testing.T) *Engine {
bot, err := NewFromSettings(&Settings{ConfigFile: config.TestFile, EnableDryRun: true}, nil)
if err != nil {
t.Fatal(err)
}
cFormat := &currency.PairFormat{Uppercase: true}
cp1 := currency.NewPair(currency.BTC, currency.USD)
cp2 := currency.NewPair(currency.BTC, currency.USDT)
err = bot.Config.RetrieveConfigCurrencyPairs(true, asset.Spot)
if err != nil {
t.Fatalf("Failed to retrieve config currency pairs. %s", err)
pairs1 := map[asset.Item]*currency.PairStore{
asset.Spot: {
AssetEnabled: convert.BoolPtr(true),
Available: currency.Pairs{cp1},
Enabled: currency.Pairs{cp1},
},
}
bot.ExchangeManager = SetupExchangeManager()
if bot.GetExchangeByName(testExchange) == nil {
err := bot.LoadExchange(testExchange, false, nil)
if err != nil {
t.Fatalf("SetupTest: Failed to load exchange: %s", err)
}
pairs2 := map[asset.Item]*currency.PairStore{
asset.Spot: {
AssetEnabled: convert.BoolPtr(true),
Available: currency.Pairs{cp2},
Enabled: currency.Pairs{cp2},
},
}
bot := &Engine{
ExchangeManager: SetupExchangeManager(),
Config: &config.Config{Exchanges: []config.ExchangeConfig{
{
Name: testExchange,
Enabled: true,
WebsocketTrafficTimeout: time.Second,
API: config.APIConfig{
Credentials: config.APICredentialsConfig{},
},
CurrencyPairs: &currency.PairsManager{
RequestFormat: cFormat,
ConfigFormat: cFormat,
UseGlobalFormat: true,
Pairs: pairs1,
},
},
{
Name: "binance",
Enabled: true,
WebsocketTrafficTimeout: time.Second,
API: config.APIConfig{
Credentials: config.APICredentialsConfig{},
},
CurrencyPairs: &currency.PairsManager{
RequestFormat: cFormat,
ConfigFormat: cFormat,
UseGlobalFormat: true,
Pairs: pairs2,
},
},
}}}
err := bot.LoadExchange(testExchange, false, nil)
if err != nil {
t.Fatalf("SetupTest: Failed to load exchange: %s", err)
}
return bot
}
func TestGetExchangeOTPs(t *testing.T) {
t.Parallel()
bot := CreateTestBot(t)
_, err := bot.GetExchangeOTPs()
if err == nil {
t.Fatal("Expected err with no exchange OTP secrets set")
}
bfxCfg, err := bot.Config.GetExchangeConfig("Bitfinex")
bnCfg, err := bot.Config.GetExchangeConfig("binance")
if err != nil {
t.Fatal(err)
}
@@ -65,7 +105,7 @@ func TestGetExchangeOTPs(t *testing.T) {
t.Fatal(err)
}
bfxCfg.API.Credentials.OTPSecret = "JBSWY3DPEHPK3PXP"
bnCfg.API.Credentials.OTPSecret = "JBSWY3DPEHPK3PXP"
bCfg.API.Credentials.OTPSecret = "JBSWY3DPEHPK3PXP"
result, err := bot.GetExchangeOTPs()
if err != nil {
@@ -75,7 +115,7 @@ func TestGetExchangeOTPs(t *testing.T) {
t.Fatal("Expected 2 OTP results")
}
bfxCfg.API.Credentials.OTPSecret = "°"
bnCfg.API.Credentials.OTPSecret = "°"
result, err = bot.GetExchangeOTPs()
if err != nil {
t.Fatal(err)
@@ -85,11 +125,12 @@ func TestGetExchangeOTPs(t *testing.T) {
}
// Flush settings
bfxCfg.API.Credentials.OTPSecret = ""
bnCfg.API.Credentials.OTPSecret = ""
bCfg.API.Credentials.OTPSecret = ""
}
func TestGetExchangeoOTPByName(t *testing.T) {
t.Parallel()
bot := CreateTestBot(t)
_, err := bot.GetExchangeOTPByName(testExchange)
if err == nil {
@@ -115,6 +156,7 @@ func TestGetExchangeoOTPByName(t *testing.T) {
}
func TestGetAuthAPISupportedExchanges(t *testing.T) {
t.Parallel()
e := CreateTestBot(t)
if result := e.GetAuthAPISupportedExchanges(); len(result) != 0 {
t.Fatal("Unexpected result", result)
@@ -131,6 +173,7 @@ func TestGetAuthAPISupportedExchanges(t *testing.T) {
}
func TestIsOnline(t *testing.T) {
t.Parallel()
e := CreateTestBot(t)
var err error
e.connectionManager, err = setupConnectionManager(&e.Config.ConnectionMonitor)
@@ -163,46 +206,60 @@ func TestIsOnline(t *testing.T) {
}
func TestGetSpecificAvailablePairs(t *testing.T) {
t.Parallel()
e := CreateTestBot(t)
c := currency.Code{
Item: &currency.Item{
Role: currency.Cryptocurrency,
Symbol: "usdt",
},
}
e.Config = &config.Config{
Exchanges: []config.ExchangeConfig{
{
Enabled: true,
Name: testExchange,
CurrencyPairs: &currency.PairsManager{Pairs: map[asset.Item]*currency.PairStore{
asset.Spot: {
AssetEnabled: convert.BoolPtr(true),
Enabled: currency.Pairs{currency.NewPair(currency.BTC, currency.USD), currency.NewPair(currency.BTC, c)},
Available: currency.Pairs{currency.NewPair(currency.BTC, currency.USD), currency.NewPair(currency.BTC, c)},
ConfigFormat: &currency.PairFormat{
Uppercase: true,
},
},
}},
},
},
}
assetType := asset.Spot
result := e.GetSpecificAvailablePairs(true, true, true, false, assetType)
btsusd, err := currency.NewPairFromStrings("BTC", "USD")
if err != nil {
t.Fatal(err)
result := e.GetSpecificAvailablePairs(true, true, true, true, assetType)
btcUSD := currency.NewPair(currency.BTC, currency.USD)
if !result.Contains(btcUSD, true) {
t.Error("Unexpected result")
}
if !result.Contains(btsusd, true) {
t.Fatal("Unexpected result")
}
btcusdt, err := currency.NewPairFromStrings("BTC", "USDT")
if err != nil {
t.Fatal(err)
}
if !result.Contains(btcusdt, false) {
t.Fatal("Unexpected result")
btcUSDT := currency.NewPair(currency.BTC, c)
if !result.Contains(btcUSDT, false) {
t.Error("Unexpected result")
}
result = e.GetSpecificAvailablePairs(true, true, false, false, assetType)
if result.Contains(btcusdt, false) {
t.Fatal("Unexpected result")
}
ltcbtc, err := currency.NewPairFromStrings("LTC", "BTC")
if err != nil {
t.Fatal(err)
if result.Contains(btcUSDT, false) {
t.Error("Unexpected result")
}
ltcBTC := currency.NewPair(currency.LTC, currency.BTC)
result = e.GetSpecificAvailablePairs(true, false, false, true, assetType)
if !result.Contains(ltcbtc, false) {
t.Fatal("Unexpected result")
if result.Contains(ltcBTC, false) {
t.Error("Unexpected result")
}
}
func TestIsRelatablePairs(t *testing.T) {
t.Parallel()
CreateTestBot(t)
xbtusd, err := currency.NewPairFromStrings("XBT", "USD")
if err != nil {
@@ -392,6 +449,7 @@ func TestIsRelatablePairs(t *testing.T) {
}
func TestGetRelatableCryptocurrencies(t *testing.T) {
t.Parallel()
CreateTestBot(t)
btcltc, err := currency.NewPairFromStrings("BTC", "LTC")
if err != nil {
@@ -415,63 +473,57 @@ func TestGetRelatableCryptocurrencies(t *testing.T) {
p := GetRelatableCryptocurrencies(btcltc)
if p.Contains(btcltc, true) {
t.Fatal("Unexpected result")
t.Error("Unexpected result")
}
if p.Contains(btcbtc, true) {
t.Fatal("Unexpected result")
t.Error("Unexpected result")
}
if p.Contains(ltcltc, true) {
t.Fatal("Unexpected result")
t.Error("Unexpected result")
}
if !p.Contains(btceth, true) {
t.Fatal("Unexpected result")
t.Error("Unexpected result")
}
p = GetRelatableCryptocurrencies(btcltc)
if p.Contains(btcltc, true) {
t.Fatal("Unexpected result")
t.Error("Unexpected result")
}
if p.Contains(btcbtc, true) {
t.Fatal("Unexpected result")
t.Error("Unexpected result")
}
if p.Contains(ltcltc, true) {
t.Fatal("Unexpected result")
t.Error("Unexpected result")
}
if !p.Contains(btceth, true) {
t.Fatal("Unexpected result")
t.Error("Unexpected result")
}
}
func TestGetRelatableFiatCurrencies(t *testing.T) {
CreateTestBot(t)
btsusd, err := currency.NewPairFromStrings("BTC", "USD")
t.Parallel()
btcUSD, err := currency.NewPairFromStrings("BTC", "USD")
if err != nil {
t.Fatal(err)
}
btceur, err := currency.NewPairFromStrings("BTC", "EUR")
btcEUR, err := currency.NewPairFromStrings("BTC", "EUR")
if err != nil {
t.Fatal(err)
}
p := GetRelatableFiatCurrencies(btsusd)
if !p.Contains(btceur, true) {
t.Fatal("Unexpected result")
p := GetRelatableFiatCurrencies(btcUSD)
if !p.Contains(btcEUR, true) {
t.Error("Unexpected result")
}
btczar, err := currency.NewPairFromStrings("BTC", "ZAR")
if err != nil {
t.Fatal(err)
}
p = GetRelatableFiatCurrencies(btsusd)
if !p.Contains(btczar, true) {
t.Fatal("Unexpected result")
if p.Contains(currency.NewPair(currency.DOGE, currency.XRP), true) {
t.Error("Unexpected result")
}
}
func TestMapCurrenciesByExchange(t *testing.T) {
t.Parallel()
e := CreateTestBot(t)
var pairs = []currency.Pair{
@@ -491,9 +543,7 @@ func TestMapCurrenciesByExchange(t *testing.T) {
}
func TestGetExchangeNamesByCurrency(t *testing.T) {
e := CreateTestBot(t)
assetType := asset.Spot
t.Parallel()
btsusd, err := currency.NewPairFromStrings("BTC", "USD")
if err != nil {
t.Fatal(err)
@@ -509,6 +559,24 @@ func TestGetExchangeNamesByCurrency(t *testing.T) {
t.Fatal(err)
}
e := CreateTestBot(t)
bf := "Bitflyer"
e.Config.Exchanges = append(e.Config.Exchanges, config.ExchangeConfig{
Enabled: true,
Name: bf,
CurrencyPairs: &currency.PairsManager{Pairs: map[asset.Item]*currency.PairStore{
asset.Spot: {
AssetEnabled: convert.BoolPtr(true),
Enabled: currency.Pairs{btcjpy},
Available: currency.Pairs{btcjpy},
ConfigFormat: &currency.PairFormat{
Uppercase: true,
},
},
}},
})
assetType := asset.Spot
result := e.GetExchangeNamesByCurrency(btsusd,
true,
assetType)
@@ -519,7 +587,7 @@ func TestGetExchangeNamesByCurrency(t *testing.T) {
result = e.GetExchangeNamesByCurrency(btcjpy,
true,
assetType)
if !common.StringDataCompare(result, "Bitflyer") {
if !common.StringDataCompare(result, bf) {
t.Fatal("Unexpected result")
}
@@ -532,6 +600,7 @@ func TestGetExchangeNamesByCurrency(t *testing.T) {
}
func TestGetSpecificOrderbook(t *testing.T) {
t.Parallel()
e := CreateTestBot(t)
var bids []orderbook.Item
@@ -580,6 +649,7 @@ func TestGetSpecificOrderbook(t *testing.T) {
}
func TestGetSpecificTicker(t *testing.T) {
t.Parallel()
e := CreateTestBot(t)
p, err := currency.NewPairFromStrings("BTC", "USD")
if err != nil {
@@ -621,6 +691,7 @@ func TestGetSpecificTicker(t *testing.T) {
}
func TestGetCollatedExchangeAccountInfoByCoin(t *testing.T) {
t.Parallel()
CreateTestBot(t)
var exchangeInfo []account.Holdings
@@ -681,6 +752,7 @@ func TestGetCollatedExchangeAccountInfoByCoin(t *testing.T) {
}
func TestGetExchangeHighestPriceByCurrencyPair(t *testing.T) {
t.Parallel()
CreateTestBot(t)
p, err := currency.NewPairFromStrings("BTC", "USD")
@@ -717,6 +789,7 @@ func TestGetExchangeHighestPriceByCurrencyPair(t *testing.T) {
}
func TestGetExchangeLowestPriceByCurrencyPair(t *testing.T) {
t.Parallel()
CreateTestBot(t)
p, err := currency.NewPairFromStrings("BTC", "USD")
@@ -753,6 +826,7 @@ func TestGetExchangeLowestPriceByCurrencyPair(t *testing.T) {
}
func TestGetCryptocurrenciesByExchange(t *testing.T) {
t.Parallel()
e := CreateTestBot(t)
_, err := e.GetCryptocurrenciesByExchange("Bitfinex", false, false, asset.Spot)
@@ -762,6 +836,7 @@ func TestGetCryptocurrenciesByExchange(t *testing.T) {
}
func TestGetExchangeNames(t *testing.T) {
t.Parallel()
bot := CreateTestBot(t)
if e := bot.GetExchangeNames(true); len(e) == 0 {
t.Error("exchange names should be populated")
@@ -779,7 +854,7 @@ func TestGetExchangeNames(t *testing.T) {
for i := range bot.Config.Exchanges {
exch, err := bot.ExchangeManager.NewExchangeByName(bot.Config.Exchanges[i].Name)
if err != nil && !errors.Is(err, ErrExchangeAlreadyLoaded) {
t.Error(err)
t.Fatal(err)
}
if exch != nil {
exch.SetDefaults()

View File

@@ -138,7 +138,7 @@ func OrdersSetup(t *testing.T) *OrderManager {
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Error(err)
t.Fatal(err)
}
exch.SetDefaults()

View File

@@ -104,7 +104,7 @@ func TestProcessPortfolio(t *testing.T) {
em := SetupExchangeManager()
exch, err := em.NewExchangeByName("Bitstamp")
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
t.Fatalf("error '%v', expected '%v'", err, nil)
}
exch.SetDefaults()
em.Add(exch)

View File

@@ -4,11 +4,11 @@ import (
"context"
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"
"reflect"
"runtime"
"strings"
"sync"
"testing"
@@ -41,7 +41,6 @@ const (
unexpectedLackOfError = "unexpected lack of error"
migrationsFolder = "migrations"
databaseFolder = "database"
databaseName = "rpctestdb.db"
)
// fExchange is a fake exchange with function overrides
@@ -50,6 +49,44 @@ type fExchange struct {
exchange.IBotExchange
}
func (f fExchange) GetHistoricCandles(p currency.Pair, a asset.Item, timeStart, _ time.Time, interval kline.Interval) (kline.Item, error) {
return kline.Item{
Exchange: "fake",
Pair: p,
Asset: a,
Interval: interval,
Candles: []kline.Candle{
{
Time: timeStart,
Open: 1337,
High: 1337,
Low: 1337,
Close: 1337,
Volume: 1337,
},
},
}, nil
}
func (f fExchange) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, timeStart, _ time.Time, interval kline.Interval) (kline.Item, error) {
return kline.Item{
Exchange: "fake",
Pair: p,
Asset: a,
Interval: interval,
Candles: []kline.Candle{
{
Time: timeStart,
Open: 1337,
High: 1337,
Low: 1337,
Close: 1337,
Volume: 1337,
},
},
}, nil
}
// FetchAccountInfo overrides testExchange's fetch account info function
// to do the bare minimum required with no API calls or credentials required
func (f fExchange) FetchAccountInfo(a asset.Item) (account.Holdings, error) {
@@ -84,6 +121,7 @@ func (f fExchange) UpdateAccountInfo(a asset.Item) (account.Holdings, error) {
}
// Sets up everything required to run any function inside rpcserver
// Only use if you require a database, this makes tests slow
func RPCTestSetup(t *testing.T) *Engine {
t.Helper()
var err error
@@ -92,24 +130,60 @@ func RPCTestSetup(t *testing.T) *Engine {
Driver: database.DBSQLite3,
ConnectionDetails: drivers.ConnectionDetails{
Host: "localhost",
Database: databaseName,
Database: "test123.db",
},
}
engerino := new(Engine)
dbm, err := SetupDatabaseConnectionManager(&dbConf)
if err != nil {
t.Fatal(err)
}
tempDir, err := ioutil.TempDir("", "")
if err != nil {
t.Fatal(err)
}
dbm.dbConn.DataPath = tempDir
engerino.DatabaseManager = dbm
var wg sync.WaitGroup
err = dbm.Start(&wg)
if err != nil {
t.Fatal(err)
}
engerino.Config = &config.Config{}
err = engerino.Config.LoadConfig(config.TestFile, true)
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatalf("SetupTest: Failed to load config: %s", err)
t.Fatal(err)
}
engerino.ExchangeManager = SetupExchangeManager()
err = engerino.LoadExchange(testExchange, false, nil)
exch.SetDefaults()
b := exch.GetBase()
cp := currency.NewPair(currency.BTC, currency.USD)
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp},
Enabled: currency.Pairs{cp},
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
em.Add(exch)
exch, err = em.NewExchangeByName("Binance")
if err != nil {
log.Fatal(err)
}
err = engerino.LoadExchange("Binance", false, nil)
if err != nil {
log.Fatal(err)
t.Fatal(err)
}
exch.SetDefaults()
b = exch.GetBase()
cp = currency.NewPair(currency.BTC, currency.USDT)
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp},
Enabled: currency.Pairs{cp},
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
em.Add(exch)
engerino.ExchangeManager = em
engerino.Config.Database = dbConf
engerino.DatabaseManager, err = SetupDatabaseConnectionManager(&engerino.Config.Database)
if err != nil {
@@ -147,7 +221,7 @@ func CleanRPCTest(t *testing.T, engerino *Engine) {
t.Error(err)
return
}
err = os.Remove(filepath.Join(common.GetDefaultDataDir(runtime.GOOS), databaseFolder, databaseName))
err = os.Remove(filepath.Join(engerino.DatabaseManager.dbConn.DataPath, engerino.DatabaseManager.cfg.Database))
if err != nil {
t.Error(err)
}
@@ -243,7 +317,7 @@ func TestConvertTradesToCandles(t *testing.T) {
},
AssetType: asset.Spot.String(),
Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
TimeInterval: int64(kline.OneHour.Duration()),
})
if !errors.Is(err, errExchangeNotLoaded) {
@@ -259,8 +333,8 @@ func TestConvertTradesToCandles(t *testing.T) {
Quote: currency.USD.String(),
},
AssetType: asset.Spot.String(),
Start: time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 2, 2, 2, 2, 2, 2, time.UTC).Format(common.SimpleTimeFormat),
Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
TimeInterval: int64(kline.OneHour.Duration()),
})
if !errors.Is(err, errNoTrades) {
@@ -269,7 +343,7 @@ func TestConvertTradesToCandles(t *testing.T) {
// add a trade
err = sqltrade.Insert(sqltrade.Data{
Timestamp: time.Date(2020, 1, 1, 1, 2, 2, 1, time.UTC),
Timestamp: time.Date(2020, 0, 0, 0, 30, 0, 0, time.UTC),
Exchange: testExchange,
Base: currency.BTC.String(),
Quote: currency.USD.String(),
@@ -292,8 +366,8 @@ func TestConvertTradesToCandles(t *testing.T) {
Quote: currency.USD.String(),
},
AssetType: asset.Spot.String(),
Start: time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 3, 2, 2, 2, 2, 2, time.UTC).Format(common.SimpleTimeFormat),
Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
TimeInterval: int64(kline.OneHour.Duration()),
})
if err != nil {
@@ -312,8 +386,8 @@ func TestConvertTradesToCandles(t *testing.T) {
Quote: currency.USD.String(),
},
AssetType: asset.Spot.String(),
Start: time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 2, 2, 2, 2, 2, 2, time.UTC).Format(common.SimpleTimeFormat),
Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
TimeInterval: int64(kline.OneHour.Duration()),
Sync: true,
})
@@ -330,8 +404,8 @@ func TestConvertTradesToCandles(t *testing.T) {
Quote: currency.USD.String(),
},
AssetType: asset.Spot.String(),
Start: time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 2, 2, 2, 2, 2, 2, time.UTC).Format(common.SimpleTimeFormat),
Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
TimeInterval: int64(kline.OneHour.Duration()),
Sync: true,
Force: true,
@@ -349,8 +423,8 @@ func TestConvertTradesToCandles(t *testing.T) {
Quote: currency.USD.String(),
},
AssetType: asset.Spot.String(),
Start: time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 2, 2, 2, 2, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
TimeInterval: int64(kline.OneHour.Duration()),
UseDb: true,
})
@@ -368,8 +442,8 @@ func TestGetHistoricCandles(t *testing.T) {
defer CleanRPCTest(t, engerino)
s := RPCServer{Engine: engerino}
// error checks
defaultStart := time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC)
defaultEnd := time.Date(2020, 1, 2, 2, 2, 2, 2, time.UTC)
defaultStart := time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC)
defaultEnd := time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC)
cp := currency.NewPair(currency.BTC, currency.USD)
_, err := s.GetHistoricCandles(context.Background(), &gctrpc.GetHistoricCandlesRequest{
Exchange: "",
@@ -382,7 +456,7 @@ func TestGetHistoricCandles(t *testing.T) {
AssetType: asset.Spot.String(),
})
if !errors.Is(err, errExchangeNotLoaded) {
t.Errorf("expected %v, received %v", errExchangeNotLoaded, err)
t.Errorf("received '%v', expected '%v'", err, errExchangeNotLoaded)
}
_, err = s.GetHistoricCandles(context.Background(), &gctrpc.GetHistoricCandlesRequest{
@@ -393,7 +467,7 @@ func TestGetHistoricCandles(t *testing.T) {
AssetType: asset.Spot.String(),
})
if !errors.Is(err, errCurrencyPairUnset) {
t.Errorf("expected %v, received %v", errCurrencyPairUnset, err)
t.Errorf("received '%v', expected '%v'", err, errCurrencyPairUnset)
}
_, err = s.GetHistoricCandles(context.Background(), &gctrpc.GetHistoricCandlesRequest{
Exchange: testExchange,
@@ -475,7 +549,7 @@ func TestGetHistoricCandles(t *testing.T) {
Price: 1337,
Amount: 1337,
Side: order.Buy,
Timestamp: time.Date(2020, 1, 2, 3, 1, 1, 7, time.UTC),
Timestamp: time.Date(2020, 0, 0, 2, 0, 0, 0, time.UTC),
})
if err != nil {
t.Error(err)
@@ -490,7 +564,7 @@ func TestGetHistoricCandles(t *testing.T) {
},
AssetType: asset.Spot.String(),
Start: defaultStart.Format(common.SimpleTimeFormat),
End: time.Date(2020, 1, 2, 4, 2, 2, 2, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 0, 0, 3, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
TimeInterval: int64(kline.OneHour.Duration()),
UseDb: true,
FillMissingWithTrades: true,
@@ -621,8 +695,8 @@ func TestFindMissingSavedCandleIntervals(t *testing.T) {
}
cp := currency.NewPair(currency.BTC, currency.USD)
// no data found response
defaultStart := time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC)
defaultEnd := time.Date(2020, 1, 2, 2, 2, 2, 2, time.UTC)
defaultStart := time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC)
defaultEnd := time.Date(2020, 0, 0, 4, 0, 0, 0, time.UTC)
var resp *gctrpc.FindMissingIntervalsResponse
_, err = s.FindMissingSavedCandleIntervals(context.Background(), &gctrpc.FindMissingCandlePeriodsRequest{
ExchangeName: testExchange,
@@ -648,7 +722,7 @@ func TestFindMissingSavedCandleIntervals(t *testing.T) {
Interval: kline.OneHour,
Candles: []kline.Candle{
{
Time: time.Date(2020, 1, 1, 2, 1, 1, 1, time.UTC),
Time: time.Date(2020, 0, 0, 0, 30, 0, 0, time.UTC),
Open: 1337,
High: 1337,
Low: 1337,
@@ -685,7 +759,7 @@ func TestFindMissingSavedCandleIntervals(t *testing.T) {
Interval: kline.OneHour,
Candles: []kline.Candle{
{
Time: time.Date(2020, 1, 1, 3, 1, 1, 1, time.UTC),
Time: time.Date(2020, 0, 0, 2, 45, 0, 0, time.UTC),
Open: 1337,
High: 1337,
Low: 1337,
@@ -719,28 +793,33 @@ func TestFindMissingSavedCandleIntervals(t *testing.T) {
}
func TestSetExchangeTradeProcessing(t *testing.T) {
engerino := RPCTestSetup(t)
defer CleanRPCTest(t, engerino)
s := RPCServer{Engine: engerino}
_, err := s.SetExchangeTradeProcessing(context.Background(), &gctrpc.SetExchangeTradeProcessingRequest{Exchange: testExchange, Status: true})
t.Parallel()
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
b := exch.GetBase()
b.Config = &config.ExchangeConfig{
Features: &config.FeaturesConfig{Enabled: config.FeaturesEnabledConfig{SaveTradeData: false}},
}
em.Add(exch)
s := RPCServer{Engine: &Engine{ExchangeManager: em}}
_, err = s.SetExchangeTradeProcessing(context.Background(), &gctrpc.SetExchangeTradeProcessingRequest{Exchange: testExchange, Status: true})
if err != nil {
t.Error(err)
return
}
exch := s.GetExchangeByName(testExchange)
base := exch.GetBase()
if !base.IsSaveTradeDataEnabled() {
if !b.IsSaveTradeDataEnabled() {
t.Error("expected true")
}
_, err = s.SetExchangeTradeProcessing(context.Background(), &gctrpc.SetExchangeTradeProcessingRequest{Exchange: testExchange, Status: false})
if err != nil {
t.Error(err)
return
}
exch = s.GetExchangeByName(testExchange)
base = exch.GetBase()
if base.IsSaveTradeDataEnabled() {
if b.IsSaveTradeDataEnabled() {
t.Error("expected false")
}
}
@@ -762,7 +841,7 @@ func TestGetRecentTrades(t *testing.T) {
},
AssetType: asset.Spot.String(),
Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
})
if !errors.Is(err, errExchangeNotLoaded) {
t.Error(err)
@@ -798,7 +877,7 @@ func TestGetHistoricTrades(t *testing.T) {
},
AssetType: asset.Spot.String(),
Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
}, nil)
if !errors.Is(err, errExchangeNotLoaded) {
t.Error(err)
@@ -812,7 +891,7 @@ func TestGetHistoricTrades(t *testing.T) {
},
AssetType: asset.Spot.String(),
Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC).Format(common.SimpleTimeFormat),
End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat),
}, nil)
if err != common.ErrFunctionNotSupported {
t.Error(err)
@@ -820,41 +899,58 @@ func TestGetHistoricTrades(t *testing.T) {
}
func TestGetAccountInfo(t *testing.T) {
bot := CreateTestBot(t)
exch := bot.ExchangeManager.GetExchangeByName(testExchange)
t.Parallel()
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
}
b := exch.GetBase()
b.Name = "fake"
b.Enabled = true
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
AssetEnabled: convert.BoolPtr(true),
}
fakeExchange := fExchange{
IBotExchange: exch,
}
bot.ExchangeManager.Add(fakeExchange)
s := RPCServer{Engine: bot}
_, err := s.GetAccountInfo(context.Background(), &gctrpc.GetAccountInfoRequest{Exchange: "fake", AssetType: asset.Spot.String()})
em.Add(fakeExchange)
s := RPCServer{Engine: &Engine{ExchangeManager: em}}
_, err = s.GetAccountInfo(context.Background(), &gctrpc.GetAccountInfoRequest{Exchange: "fake", AssetType: asset.Spot.String()})
if !errors.Is(err, nil) {
t.Errorf("expected %v, received %v", errAssetTypeDisabled, nil)
t.Errorf("received '%v', expected '%v'", err, nil)
}
}
func TestUpdateAccountInfo(t *testing.T) {
bot := CreateTestBot(t)
exch := bot.ExchangeManager.GetExchangeByName(testExchange)
t.Parallel()
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(testExchange)
if err != nil {
t.Fatal(err)
}
b := exch.GetBase()
b.Name = "fake"
b.Enabled = true
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
AssetEnabled: convert.BoolPtr(true),
}
fakeExchange := fExchange{
IBotExchange: exch,
}
bot.ExchangeManager.Add(fakeExchange)
s := RPCServer{Engine: bot}
em.Add(fakeExchange)
s := RPCServer{Engine: &Engine{ExchangeManager: em}}
_, err := s.GetAccountInfo(context.Background(), &gctrpc.GetAccountInfoRequest{Exchange: "fake", AssetType: asset.Spot.String()})
_, err = s.GetAccountInfo(context.Background(), &gctrpc.GetAccountInfoRequest{Exchange: "fake", AssetType: asset.Spot.String()})
if !errors.Is(err, nil) {
t.Errorf("expected %v, received %v", nil, err)
t.Errorf("received '%v', expected '%v'", err, nil)
}
_, err = s.UpdateAccountInfo(context.Background(), &gctrpc.GetAccountInfoRequest{Exchange: "fake", AssetType: asset.Futures.String()})
if !errors.Is(err, errAssetTypeDisabled) {
t.Errorf("expected %v, received %v", errAssetTypeDisabled, err)
t.Errorf("received '%v', expected '%v'", err, errAssetTypeDisabled)
}
_, err = s.UpdateAccountInfo(context.Background(), &gctrpc.GetAccountInfoRequest{
@@ -862,15 +958,40 @@ func TestUpdateAccountInfo(t *testing.T) {
AssetType: asset.Spot.String(),
})
if !errors.Is(err, nil) {
t.Errorf("expected %v, received %v", nil, err)
t.Errorf("received '%v', expected '%v'", err, nil)
}
}
func TestGetOrders(t *testing.T) {
exchName := "binance"
engerino := RPCTestSetup(t)
defer CleanRPCTest(t, engerino)
s := RPCServer{Engine: engerino}
t.Parallel()
exchName := "Binance"
engerino := &Engine{}
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(exchName)
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
b := exch.GetBase()
cp := currency.NewPair(currency.BTC, currency.USDT)
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp},
Enabled: currency.Pairs{cp},
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
em.Add(exch)
var wg sync.WaitGroup
om, err := SetupOrderManager(em, engerino.CommunicationsManager, &wg, false)
if !errors.Is(err, nil) {
t.Errorf("received '%v', expected '%v'", err, nil)
}
err = om.Start()
if !errors.Is(err, nil) {
t.Errorf("received '%v', expected '%v'", err, nil)
}
s := RPCServer{Engine: &Engine{ExchangeManager: em, OrderManager: om}}
p := &gctrpc.CurrencyPair{
Delimiter: "-",
@@ -878,9 +999,9 @@ func TestGetOrders(t *testing.T) {
Quote: currency.USDT.String(),
}
_, err := s.GetOrders(context.Background(), nil)
_, err = s.GetOrders(context.Background(), nil)
if !errors.Is(err, errInvalidArguments) {
t.Errorf("expected %v, received %v", errInvalidArguments, err)
t.Errorf("received '%v', expected '%v'", err, errInvalidArguments)
}
_, err = s.GetOrders(context.Background(), &gctrpc.GetOrdersRequest{
@@ -888,7 +1009,7 @@ func TestGetOrders(t *testing.T) {
Pair: p,
})
if !errors.Is(err, errExchangeNotLoaded) {
t.Errorf("expected %v, received %v", errExchangeNotLoaded, err)
t.Errorf("received '%v', expected '%v'", errExchangeNotLoaded, err)
}
_, err = s.GetOrders(context.Background(), &gctrpc.GetOrdersRequest{
@@ -896,7 +1017,7 @@ func TestGetOrders(t *testing.T) {
AssetType: asset.Spot.String(),
})
if !errors.Is(err, errCurrencyPairUnset) {
t.Errorf("expected %v, received %v", errCurrencyPairUnset, err)
t.Errorf("received '%v', expected '%v'", err, errCurrencyPairUnset)
}
_, err = s.GetOrders(context.Background(), &gctrpc.GetOrdersRequest{
@@ -904,7 +1025,7 @@ func TestGetOrders(t *testing.T) {
Pair: p,
})
if !errors.Is(err, asset.ErrNotSupported) {
t.Errorf("expected %v, received %v", asset.ErrNotSupported, err)
t.Errorf("received '%v', expected '%v'", err, asset.ErrNotSupported)
}
_, err = s.GetOrders(context.Background(), &gctrpc.GetOrdersRequest{
@@ -929,11 +1050,6 @@ func TestGetOrders(t *testing.T) {
t.Errorf("received '%v', expected '%v'", err, exchange.ErrAuthenticatedRequestWithoutCredentialsSet)
}
exch := engerino.GetExchangeByName(exchName)
if exch == nil {
t.Fatal("expected an exchange")
}
b := exch.GetBase()
b.API.Credentials.Key = "test"
b.API.Credentials.Secret = "test"
b.API.AuthenticatedSupport = true
@@ -949,17 +1065,35 @@ func TestGetOrders(t *testing.T) {
}
func TestGetOrder(t *testing.T) {
t.Parallel()
exchName := "Binance"
engerino := RPCTestSetup(t)
defer CleanRPCTest(t, engerino)
s := RPCServer{Engine: engerino}
var wg sync.WaitGroup
var err error
engerino.OrderManager, err = SetupOrderManager(engerino.ExchangeManager, engerino.CommunicationsManager, &wg, false)
if !errors.Is(err, nil) {
t.Errorf("expected %v, received %v", errInvalidArguments, nil)
engerino := &Engine{}
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(exchName)
if err != nil {
t.Fatal(err)
}
exch.SetDefaults()
b := exch.GetBase()
cp := currency.NewPair(currency.BTC, currency.USDT)
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
b.CurrencyPairs.Pairs[asset.Spot] = &currency.PairStore{
Available: currency.Pairs{cp},
Enabled: currency.Pairs{cp},
AssetEnabled: convert.BoolPtr(true),
ConfigFormat: &currency.PairFormat{Uppercase: true},
RequestFormat: &currency.PairFormat{Uppercase: true}}
em.Add(exch)
var wg sync.WaitGroup
om, err := SetupOrderManager(em, engerino.CommunicationsManager, &wg, false)
if !errors.Is(err, nil) {
t.Errorf("received '%v', expected '%v'", err, nil)
}
err = om.Start()
if !errors.Is(err, nil) {
t.Errorf("received '%v', expected '%v'", err, nil)
}
s := RPCServer{Engine: &Engine{ExchangeManager: em, OrderManager: om}}
p := &gctrpc.CurrencyPair{
Delimiter: "-",
Base: "BTC",
@@ -968,7 +1102,7 @@ func TestGetOrder(t *testing.T) {
_, err = s.GetOrder(context.Background(), nil)
if !errors.Is(err, errInvalidArguments) {
t.Errorf("expected %v, received %v", errInvalidArguments, err)
t.Errorf("received '%v', expected '%v'", err, errInvalidArguments)
}
_, err = s.GetOrder(context.Background(), &gctrpc.GetOrderRequest{
@@ -978,7 +1112,7 @@ func TestGetOrder(t *testing.T) {
Asset: "spot",
})
if !errors.Is(err, errExchangeNotLoaded) {
t.Errorf("expected %v, received %v", errExchangeNotLoaded, err)
t.Errorf("received '%v', expected '%v'", err, errExchangeNotLoaded)
}
_, err = s.GetOrder(context.Background(), &gctrpc.GetOrderRequest{
@@ -988,7 +1122,7 @@ func TestGetOrder(t *testing.T) {
Asset: "",
})
if !errors.Is(err, errCurrencyPairUnset) {
t.Errorf("expected %v, received %v", errCurrencyPairUnset, err)
t.Errorf("received '%v', expected '%v'", err, errCurrencyPairUnset)
}
_, err = s.GetOrder(context.Background(), &gctrpc.GetOrderRequest{
@@ -998,17 +1132,7 @@ func TestGetOrder(t *testing.T) {
Asset: "",
})
if !errors.Is(err, asset.ErrNotSupported) {
t.Errorf("expected %v, received %v", asset.ErrNotSupported, err)
}
s.OrderManager, err = SetupOrderManager(engerino.ExchangeManager, engerino.CommunicationsManager, &engerino.ServicesWG, engerino.Settings.Verbose)
if err != nil {
t.Fatal(err)
}
err = s.OrderManager.Start()
if err != nil {
t.Fatal(err)
t.Errorf("received '%v', expected '%v'", err, asset.ErrNotSupported)
}
_, err = s.GetOrder(context.Background(), &gctrpc.GetOrderRequest{
@@ -1018,7 +1142,7 @@ func TestGetOrder(t *testing.T) {
Asset: asset.Spot.String(),
})
if !errors.Is(err, ErrOrderIDCannotBeEmpty) {
t.Errorf("expected %v, received %v", ErrOrderIDCannotBeEmpty, err)
t.Errorf("received '%v', expected '%v'", err, ErrOrderIDCannotBeEmpty)
}
_, err = s.GetOrder(context.Background(), &gctrpc.GetOrderRequest{
Exchange: exchName,
@@ -1032,8 +1156,8 @@ func TestGetOrder(t *testing.T) {
}
func TestCheckVars(t *testing.T) {
t.Parallel()
var e exchange.IBotExchange
err := checkParams("Binance", e, asset.Spot, currency.NewPair(currency.BTC, currency.USDT))
if !errors.Is(err, errExchangeNotLoaded) {
t.Errorf("expected %v, got %v", errExchangeNotLoaded, err)
@@ -1130,6 +1254,7 @@ func TestCheckVars(t *testing.T) {
}
func TestParseEvents(t *testing.T) {
t.Parallel()
var exchangeName = "Binance"
var testData []*withdraw.Response
for x := 0; x < 5; x++ {
@@ -1294,7 +1419,7 @@ func TestGetDataHistoryJobDetails(t *testing.T) {
t.Fatal("expected job")
}
if !strings.EqualFold(resp.Nickname, "TestGetDataHistoryJobDetails") {
t.Errorf("received %v, expected %v", "TestGetDataHistoryJobDetails", resp.Nickname)
t.Errorf("received %v, expected %v", resp.Nickname, "TestGetDataHistoryJobDetails")
}
}

View File

@@ -13,6 +13,7 @@ import (
)
func TestSetupSyncManager(t *testing.T) {
t.Parallel()
_, err := setupSyncManager(&Config{}, nil, nil, nil)
if !errors.Is(err, errNoSyncItemsEnabled) {
t.Errorf("error '%v', expected '%v'", err, errNoSyncItemsEnabled)
@@ -38,6 +39,7 @@ func TestSetupSyncManager(t *testing.T) {
}
func TestSyncManagerStart(t *testing.T) {
t.Parallel()
m, err := setupSyncManager(&Config{SyncTrades: true}, &ExchangeManager{}, nil, &config.RemoteControlConfig{})
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
@@ -69,6 +71,7 @@ func TestSyncManagerStart(t *testing.T) {
}
func TestSyncManagerStop(t *testing.T) {
t.Parallel()
var m *syncManager
err := m.Stop()
if !errors.Is(err, ErrNilSubsystem) {
@@ -103,6 +106,7 @@ func TestSyncManagerStop(t *testing.T) {
}
func TestPrintCurrencyFormat(t *testing.T) {
t.Parallel()
c := printCurrencyFormat(1337, currency.BTC)
if c == "" {
t.Error("expected formatted currency")
@@ -110,6 +114,7 @@ func TestPrintCurrencyFormat(t *testing.T) {
}
func TestPrintConvertCurrencyFormat(t *testing.T) {
t.Parallel()
c := printConvertCurrencyFormat(currency.BTC, 1337, currency.USD)
if c == "" {
t.Error("expected formatted currency")
@@ -117,6 +122,7 @@ func TestPrintConvertCurrencyFormat(t *testing.T) {
}
func TestPrintTickerSummary(t *testing.T) {
t.Parallel()
var m *syncManager
m.PrintTickerSummary(&ticker.Price{}, "REST", nil)
@@ -155,6 +161,7 @@ func TestPrintTickerSummary(t *testing.T) {
}
func TestPrintOrderbookSummary(t *testing.T) {
t.Parallel()
var m *syncManager
m.PrintOrderbookSummary(nil, "REST", nil)
@@ -196,5 +203,7 @@ func TestPrintOrderbookSummary(t *testing.T) {
}
func TestRelayWebsocketEvent(t *testing.T) {
t.Parallel()
relayWebsocketEvent(nil, "", "", "")
}

View File

@@ -127,7 +127,7 @@ func TestWebsocketRoutineManagerHandleData(t *testing.T) {
em := SetupExchangeManager()
exch, err := em.NewExchangeByName(exchName)
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
t.Fatalf("error '%v', expected '%v'", err, nil)
}
exch.SetDefaults()
em.Add(exch)

View File

@@ -40,29 +40,25 @@ func TestSubmitWithdrawal(t *testing.T) {
if err != nil {
t.Fatal(err)
}
banking.Accounts = append(banking.Accounts,
banking.Account{
Enabled: true,
ID: "test-bank-01",
BankName: "Test Bank",
BankAddress: "42 Bank Street",
BankPostalCode: "13337",
BankPostalCity: "Satoshiville",
BankCountry: "Japan",
AccountName: "Satoshi Nakamoto",
AccountNumber: "0234",
BSBNumber: "123456",
SWIFTCode: "91272837",
IBAN: "98218738671897",
SupportedCurrencies: "AUD,USD",
SupportedExchanges: "Binance",
},
)
bank, err := banking.GetBankAccountByID("test-bank-01")
if err != nil {
t.Error(err)
bank := banking.Account{
Enabled: true,
ID: "test-bank-01",
BankName: "Test Bank",
BankAddress: "42 Bank Street",
BankPostalCode: "13337",
BankPostalCity: "Satoshiville",
BankCountry: "Japan",
AccountName: "Satoshi Nakamoto",
AccountNumber: "0234",
BSBNumber: "123456",
SWIFTCode: "91272837",
IBAN: "98218738671897",
SupportedCurrencies: "AUD,USD",
SupportedExchanges: "Binance",
}
banking.AppendAccounts(bank)
req := &withdraw.Request{
Exchange: exchangeName,
Currency: currency.AUD,
@@ -70,7 +66,7 @@ func TestSubmitWithdrawal(t *testing.T) {
Amount: 1.0,
Type: withdraw.Fiat,
Fiat: withdraw.FiatRequest{
Bank: *bank,
Bank: bank,
},
}
_, err = m.SubmitWithdrawal(req)

View File

@@ -1167,7 +1167,6 @@ func TestWsNewOffer(t *testing.T) {
if err != nil {
t.Error(err)
}
time.Sleep(time.Second)
}
// TestWsCancelOffer dials websocket, sends cancel offer request.
@@ -1182,7 +1181,6 @@ func TestWsCancelOffer(t *testing.T) {
if err != nil {
t.Error(err)
}
time.Sleep(time.Second)
}
func TestConvertSymbolToDepositMethod(t *testing.T) {
@@ -1313,7 +1311,8 @@ func TestGetHistoricCandles(t *testing.T) {
t.Fatal(err)
}
startTime := time.Now().Add(-time.Hour * 24)
_, err = b.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin)
endTime := time.Now().Add(-time.Hour * 20)
_, err = b.GetHistoricCandles(currencyPair, asset.Spot, startTime, endTime, kline.OneHour)
if err != nil {
t.Fatal(err)
}
@@ -1330,12 +1329,13 @@ func TestGetHistoricCandlesExtended(t *testing.T) {
t.Fatal(err)
}
startTime := time.Now().Add(-time.Hour * 24)
_, err = b.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, time.Now(), kline.OneHour)
endTime := time.Now().Add(-time.Hour * 20)
_, err = b.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, endTime, kline.OneHour)
if err != nil {
t.Fatal(err)
}
_, err = b.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin*1337)
_, err = b.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, endTime, kline.OneMin*1337)
if err == nil {
t.Fatal(err)
}

View File

@@ -524,7 +524,7 @@ func (b *Bitfinex) GetWithdrawalsHistory(c currency.Code) (resp []exchange.Withd
// GetRecentTrades returns the most recent trades for a currency and asset
func (b *Bitfinex) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) {
return b.GetHistoricTrades(p, assetType, time.Now().Add(-time.Hour), time.Now())
return b.GetHistoricTrades(p, assetType, time.Now().Add(-time.Minute*15), time.Now())
}
// GetHistoricTrades returns historic trade data within the timeframe provided

View File

@@ -51,7 +51,6 @@ func TestMain(m *testing.M) {
if err != nil {
log.Fatal("Bitmex setup error", err)
}
b.UpdateTradablePairs(true)
os.Exit(m.Run())
}
@@ -64,17 +63,12 @@ func TestStart(t *testing.T) {
func TestGetFullFundingHistory(t *testing.T) {
t.Parallel()
_, err := b.GetFullFundingHistory("", "", "", "", "", true, time.Time{}, time.Time{})
_, err := b.GetFullFundingHistory("", "", "", "", "", true, time.Now().Add(-time.Minute), time.Now())
if err != nil {
t.Error(err)
}
_, err = b.GetFullFundingHistory("", "", "", "", "", true, time.Now().Add(-time.Hour*8), time.Now())
if err != nil {
t.Error(err)
}
_, err = b.GetFullFundingHistory("LTCUSD", "1", "", "", "", true, time.Now().Add(time.Hour*-24), time.Now())
_, err = b.GetFullFundingHistory("LTCUSD", "1", "", "", "", true, time.Now().Add(-time.Minute), time.Now())
if err != nil {
t.Error(err)
}
@@ -82,6 +76,9 @@ func TestGetFullFundingHistory(t *testing.T) {
func TestGetUrgentAnnouncement(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.GetUrgentAnnouncement()
if err == nil {
t.Error("GetUrgentAnnouncement() Expected error")
@@ -90,6 +87,9 @@ func TestGetUrgentAnnouncement(t *testing.T) {
func TestGetAPIKeys(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.GetAPIKeys()
if err == nil {
t.Error("GetAPIKeys() Expected error")
@@ -98,6 +98,7 @@ func TestGetAPIKeys(t *testing.T) {
func TestRemoveAPIKey(t *testing.T) {
t.Parallel()
_, err := b.RemoveAPIKey(APIKeyParams{APIKeyID: "1337"})
if err == nil {
t.Error("RemoveAPIKey() Expected error")
@@ -106,6 +107,9 @@ func TestRemoveAPIKey(t *testing.T) {
func TestDisableAPIKey(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.DisableAPIKey(APIKeyParams{APIKeyID: "1337"})
if err == nil {
t.Error("DisableAPIKey() Expected error")
@@ -114,6 +118,9 @@ func TestDisableAPIKey(t *testing.T) {
func TestEnableAPIKey(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.EnableAPIKey(APIKeyParams{APIKeyID: "1337"})
if err == nil {
t.Error("EnableAPIKey() Expected error")
@@ -122,7 +129,7 @@ func TestEnableAPIKey(t *testing.T) {
func TestGetTrollboxMessages(t *testing.T) {
t.Parallel()
_, err := b.GetTrollboxMessages(ChatGetParams{Count: 5})
_, err := b.GetTrollboxMessages(ChatGetParams{Count: 1})
if err != nil {
t.Error("GetTrollboxMessages() error", err)
}
@@ -130,6 +137,9 @@ func TestGetTrollboxMessages(t *testing.T) {
func TestSendTrollboxMessage(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.SendTrollboxMessage(ChatSendParams{
ChannelID: 1337,
Message: "Hello,World!"})
@@ -156,6 +166,9 @@ func TestGetTrollboxConnectedUsers(t *testing.T) {
func TestGetAccountExecutions(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.GetAccountExecutions(&GenericRequestParams{})
if err == nil {
t.Error("GetAccountExecutions() Expected error")
@@ -164,6 +177,9 @@ func TestGetAccountExecutions(t *testing.T) {
func TestGetAccountExecutionTradeHistory(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.GetAccountExecutionTradeHistory(&GenericRequestParams{})
if err == nil {
t.Error("GetAccountExecutionTradeHistory() Expected error")
@@ -180,7 +196,9 @@ func TestGetFundingHistory(t *testing.T) {
func TestGetInstruments(t *testing.T) {
t.Parallel()
_, err := b.GetInstruments(&GenericRequestParams{})
_, err := b.GetInstruments(&GenericRequestParams{
Symbol: "XRPUSD",
})
if err != nil {
t.Error("GetInstruments() error", err)
}
@@ -260,6 +278,9 @@ func TestGetLiquidationOrders(t *testing.T) {
func TestGetCurrentNotifications(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.GetCurrentNotifications()
if err == nil {
t.Error("GetCurrentNotifications() Expected error")
@@ -268,6 +289,9 @@ func TestGetCurrentNotifications(t *testing.T) {
func TestAmendOrder(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.AmendOrder(&OrderAmendParams{})
if err == nil {
t.Error("AmendOrder() Expected error")
@@ -276,6 +300,9 @@ func TestAmendOrder(t *testing.T) {
func TestCreateOrder(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.CreateOrder(&OrderNewParams{Symbol: "XBTM15",
Price: 219.0,
ClientOrderID: "mm_bitmex_1a/oemUeQ4CAJZgP3fjHsA",
@@ -287,6 +314,9 @@ func TestCreateOrder(t *testing.T) {
func TestCancelOrders(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.CancelOrders(&OrderCancelParams{})
if err == nil {
t.Error("CancelOrders() Expected error")
@@ -295,6 +325,9 @@ func TestCancelOrders(t *testing.T) {
func TestCancelAllOrders(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.CancelAllExistingOrders(OrderCancelAllParams{})
if err == nil {
t.Error("CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error)", err)
@@ -303,6 +336,9 @@ func TestCancelAllOrders(t *testing.T) {
func TestAmendBulkOrders(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.AmendBulkOrders(OrderAmendBulkParams{})
if err == nil {
t.Error("AmendBulkOrders() Expected error")
@@ -311,6 +347,9 @@ func TestAmendBulkOrders(t *testing.T) {
func TestCreateBulkOrders(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.CreateBulkOrders(OrderNewBulkParams{})
if err == nil {
t.Error("CreateBulkOrders() Expected error")
@@ -319,6 +358,9 @@ func TestCreateBulkOrders(t *testing.T) {
func TestCancelAllOrdersAfterTime(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.CancelAllOrdersAfterTime(OrderCancelAllAfterParams{})
if err == nil {
t.Error("CancelAllOrdersAfterTime() Expected error")
@@ -426,7 +468,7 @@ func TestGetTrade(t *testing.T) {
_, err := b.GetTrade(&GenericRequestParams{
Symbol: "XBT",
Reverse: false,
StartTime: time.Now().Add(-time.Hour).Format(time.RFC3339),
StartTime: time.Now().Add(-time.Minute).Format(time.RFC3339),
})
if err != nil {
t.Error("GetTrade() error", err)
@@ -437,7 +479,7 @@ func TestGetPreviousTrades(t *testing.T) {
t.Parallel()
_, err := b.GetPreviousTrades(&TradeGetBucketedParams{
Symbol: "XBTBTC",
Start: int32(time.Now().Add(-time.Hour * 24).Unix()),
Start: int32(time.Now().Add(-time.Hour).Unix()),
Columns: "open,high,low,close,volume",
})
if err == nil {
@@ -1043,7 +1085,7 @@ func TestGetHistoricTrades(t *testing.T) {
t.Fatal(err)
}
currencyPair := b.CurrencyPairs.Pairs[asset.Futures].Available[0]
_, err = b.GetHistoricTrades(currencyPair, asset.Futures, time.Now().Add(-time.Minute*15), time.Now())
_, err = b.GetHistoricTrades(currencyPair, asset.Futures, time.Now().Add(-time.Minute), time.Now())
if err != nil {
t.Error(err)
}

View File

@@ -453,7 +453,7 @@ func (b *Bitmex) GetWithdrawalsHistory(c currency.Code) (resp []exchange.Withdra
// GetRecentTrades returns the most recent trades for a currency and asset
func (b *Bitmex) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) {
return b.GetHistoricTrades(p, assetType, time.Now().Add(-time.Hour), time.Now())
return b.GetHistoricTrades(p, assetType, time.Now().Add(-time.Minute*15), time.Now())
}
// GetHistoricTrades returns historic trade data within the timeframe provided

View File

@@ -737,7 +737,7 @@ func TestBTCMarkets_GetHistoricCandles(t *testing.T) {
}
func TestBTCMarkets_GetHistoricCandlesExtended(t *testing.T) {
start := time.Now().AddDate(0, 0, -1001)
start := time.Now().AddDate(0, 0, -2)
end := time.Now()
p, err := currency.NewPairFromString(BTCAUD)
if err != nil {

View File

@@ -653,7 +653,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) {
if err != nil {
t.Fatal(err)
}
startTime := time.Now().Add(-time.Hour * 24)
startTime := time.Now().Add(-time.Hour * 2)
_, err = c.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, time.Now(), kline.OneHour)
if err != nil {
t.Fatal(err)

View File

@@ -348,13 +348,23 @@ func TestSetAPICredentialDefaults(t *testing.T) {
}
func TestSetAutoPairDefaults(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig(config.TestFile, true)
if err != nil {
t.Fatalf("TestSetAutoPairDefaults failed to load config file. Error: %s", err)
}
t.Parallel()
bs := "Bitstamp"
cfg := &config.Config{Exchanges: []config.ExchangeConfig{
{
Name: bs,
CurrencyPairs: &currency.PairsManager{},
Features: &config.FeaturesConfig{
Supports: config.FeaturesSupportedConfig{
RESTCapabilities: protocol.Features{
AutoPairUpdates: true,
},
},
},
},
}}
exch, err := cfg.GetExchangeConfig("Bitstamp")
exch, err := cfg.GetExchangeConfig(bs)
if err != nil {
t.Fatalf("TestSetAutoPairDefaults load config failed. Error %s", err)
}
@@ -369,7 +379,7 @@ func TestSetAutoPairDefaults(t *testing.T) {
exch.Features.Supports.RESTCapabilities.AutoPairUpdates = false
exch, err = cfg.GetExchangeConfig("Bitstamp")
exch, err = cfg.GetExchangeConfig(bs)
if err != nil {
t.Fatalf("TestSetAutoPairDefaults load config failed. Error %s", err)
}
@@ -1467,10 +1477,14 @@ func TestSetPairs(t *testing.T) {
}
func TestUpdatePairs(t *testing.T) {
cfg := config.GetConfig()
err := cfg.LoadConfig(config.TestFile, true)
if err != nil {
t.Fatal("TestUpdatePairs failed to load config")
t.Parallel()
cfg := &config.Config{
Exchanges: []config.ExchangeConfig{
{
Name: defaultTestExchange,
CurrencyPairs: &currency.PairsManager{},
},
},
}
exchCfg, err := cfg.GetExchangeConfig(defaultTestExchange)

View File

@@ -1119,7 +1119,7 @@ func TestGetHistoricCandles(t *testing.T) {
t.Fatal(err)
}
start := time.Date(2019, 11, 12, 0, 0, 0, 0, time.UTC)
end := start.AddDate(0, 0, 5)
end := start.AddDate(0, 0, 2)
_, err = f.GetHistoricCandles(currencyPair, asset.Spot, start, end, kline.OneDay)
if err != nil {
t.Fatal(err)
@@ -1133,8 +1133,8 @@ func TestGetHistoricCandlesExtended(t *testing.T) {
t.Fatal(err)
}
start := time.Date(2019, 11, 12, 0, 0, 0, 0, time.UTC)
end := start.AddDate(0, 0, 5)
_, err = f.GetHistoricCandlesExtended(currencyPair, asset.Spot, start, end, kline.OneMin)
end := start.AddDate(0, 0, 2)
_, err = f.GetHistoricCandlesExtended(currencyPair, asset.Spot, start, end, kline.OneDay)
if err != nil {
t.Fatal(err)
}

View File

@@ -471,7 +471,7 @@ func (f *FTX) GetWithdrawalsHistory(c currency.Code) (resp []exchange.Withdrawal
// GetRecentTrades returns the most recent trades for a currency and asset
func (f *FTX) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) {
return f.GetHistoricTrades(p, assetType, time.Now().Add(-time.Hour), time.Now())
return f.GetHistoricTrades(p, assetType, time.Now().Add(-time.Minute*15), time.Now())
}
// GetHistoricTrades returns historic trade data within the timeframe provided

View File

@@ -750,7 +750,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) {
if err != nil {
t.Fatal(err)
}
startTime := time.Now().Add(-time.Hour * 6)
startTime := time.Now().Add(-time.Minute * 2)
_, err = g.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin)
if err != nil {
t.Fatal(err)

View File

@@ -1190,7 +1190,7 @@ func TestGetHistoricTrades(t *testing.T) {
tEnd := time.Date(2020, 6, 7, 0, 0, 0, 0, time.UTC)
if !mockTests {
tStart = time.Date(time.Now().Year(), time.Now().Month(), 1, 0, 0, 0, 0, time.UTC)
tEnd = time.Date(time.Now().Year(), time.Now().Month(), 1, 1, 0, 0, 0, time.UTC)
tEnd = time.Date(time.Now().Year(), time.Now().Month(), 1, 0, 15, 0, 0, time.UTC)
}
_, err = g.GetHistoricTrades(currencyPair, asset.Spot, tStart, tEnd)
if err != nil {

View File

@@ -465,7 +465,7 @@ func (h *HitBTC) GetWithdrawalsHistory(c currency.Code) (resp []exchange.Withdra
// GetRecentTrades returns the most recent trades for a currency and asset
func (h *HitBTC) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) {
return h.GetHistoricTrades(p, assetType, time.Now().Add(-time.Hour), time.Now())
return h.GetHistoricTrades(p, assetType, time.Now().Add(-time.Minute*15), time.Now())
}
// GetHistoricTrades returns historic trade data within the timeframe provided

View File

@@ -135,7 +135,7 @@ func TestFGetKlineData(t *testing.T) {
if err != nil {
t.Error(err)
}
_, err = h.FGetKlineData(cp, "5min", 5, time.Time{}, time.Time{})
_, err = h.FGetKlineData(cp, "5min", 5, time.Now().Add(-time.Minute*5), time.Now())
if err != nil {
t.Error(err)
}
@@ -654,7 +654,8 @@ func TestFetchTradablePairs(t *testing.T) {
}
}
func TestUpdateTicker(t *testing.T) {
func TestUpdateTickerSpot(t *testing.T) {
t.Parallel()
sp, err := currency.NewPairFromString("BTC_USDT")
if err != nil {
t.Error(err)
@@ -663,6 +664,10 @@ func TestUpdateTicker(t *testing.T) {
if err != nil {
t.Error(err)
}
}
func TestUpdateTickerCMF(t *testing.T) {
t.Parallel()
cp1, err := currency.NewPairFromString("BTC-USD")
if err != nil {
t.Error(err)
@@ -671,6 +676,10 @@ func TestUpdateTicker(t *testing.T) {
if err != nil {
t.Error(err)
}
}
func TestUpdateTickerFutures(t *testing.T) {
t.Parallel()
tradablePairs, err := h.FetchTradablePairs(asset.Futures)
if err != nil {
t.Error(err)
@@ -688,7 +697,7 @@ func TestUpdateTicker(t *testing.T) {
}
}
func TestUpdateOrderbook(t *testing.T) {
func TestUpdateOrderbookSpot(t *testing.T) {
t.Parallel()
sp, err := currency.NewPairFromString("BTC_USDT")
if err != nil {
@@ -698,7 +707,11 @@ func TestUpdateOrderbook(t *testing.T) {
if err != nil {
t.Error(err)
}
cp1, err := currency.NewPairFromString("BTC_USD")
}
func TestUpdateOrderbookCMF(t *testing.T) {
t.Parallel()
cp1, err := currency.NewPairFromString("BTC-USD")
if err != nil {
t.Error(err)
}
@@ -706,6 +719,10 @@ func TestUpdateOrderbook(t *testing.T) {
if err != nil {
t.Error(err)
}
}
func TestUpdateOrderbookFuture(t *testing.T) {
t.Parallel()
tradablePairs, err := h.FetchTradablePairs(asset.Futures)
if err != nil {
t.Error(err)
@@ -1550,7 +1567,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) {
if err != nil {
t.Fatal(err)
}
startTime := time.Now().Add(-time.Hour * 1)
startTime := time.Now().Add(-time.Minute * 2)
_, err = h.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin)
if err != nil {
t.Fatal(err)

View File

@@ -32,6 +32,7 @@ var (
)
func TestValidateData(t *testing.T) {
t.Parallel()
err := validateData(nil)
if err == nil {
t.Error("error cannot be nil")
@@ -90,6 +91,7 @@ func TestValidateData(t *testing.T) {
}
func TestCreateKline(t *testing.T) {
t.Parallel()
c, err := CreateKline(nil,
OneMin,
currency.NewPair(currency.BTC, currency.USD),
@@ -135,24 +137,28 @@ func TestCreateKline(t *testing.T) {
}
func TestKlineWord(t *testing.T) {
t.Parallel()
if OneDay.Word() != "oneday" {
t.Fatalf("unexpected result: %v", OneDay.Word())
}
}
func TestKlineDuration(t *testing.T) {
t.Parallel()
if OneDay.Duration() != time.Hour*24 {
t.Fatalf("unexpected result: %v", OneDay.Duration())
}
}
func TestKlineShort(t *testing.T) {
t.Parallel()
if OneDay.Short() != "24h" {
t.Fatalf("unexpected result: %v", OneDay.Short())
}
}
func TestDurationToWord(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
interval Interval
@@ -254,6 +260,7 @@ func TestDurationToWord(t *testing.T) {
}
func TestKlineErrors(t *testing.T) {
t.Parallel()
v := ErrorKline{
Interval: OneYear,
Pair: currency.NewPair(currency.BTC, currency.AUD),
@@ -278,6 +285,7 @@ func TestKlineErrors(t *testing.T) {
}
func TestTotalCandlesPerInterval(t *testing.T) {
t.Parallel()
start := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
end := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
@@ -399,7 +407,8 @@ func TestTotalCandlesPerInterval(t *testing.T) {
}
func TestCalculateCandleDateRanges(t *testing.T) {
pt := time.Date(1999, 1, 1, 0, 0, 0, 0, time.UTC)
t.Parallel()
pt := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
ft := time.Date(2222, 1, 1, 0, 0, 0, 0, time.UTC)
et := time.Date(2020, 1, 1, 1, 0, 0, 0, time.UTC)
nt := time.Time{}
@@ -424,31 +433,31 @@ func TestCalculateCandleDateRanges(t *testing.T) {
t.Errorf("received %v expected %v", err, common.ErrStartEqualsEnd)
}
v, err := CalculateCandleDateRanges(pt, et, OneMin, 300)
v, err := CalculateCandleDateRanges(pt, et, OneWeek, 300)
if err != nil {
t.Error(err)
}
if v.Ranges[0].Start.Ticks != time.Unix(915148800, 0).Unix() {
t.Errorf("expected %v received %v", 915148800, v.Ranges[0].Start.Ticks)
if !v.Ranges[0].Start.Time.Equal(time.Unix(1546214400, 0)) {
t.Errorf("expected %v received %v", 1546214400, v.Ranges[0].Start.Ticks)
}
v, err = CalculateCandleDateRanges(pt, et, OneDay, 100)
v, err = CalculateCandleDateRanges(pt, et, OneWeek, 100)
if err != nil {
t.Error(err)
}
if len(v.Ranges) != 77 {
t.Fatalf("expected %v received %v", 77, len(v.Ranges))
if len(v.Ranges) != 1 {
t.Fatalf("expected %v received %v", 1, len(v.Ranges))
}
if len(v.Ranges[0].Intervals) != 100 {
t.Errorf("expected %v received %v", 100, len(v.Ranges[0].Intervals))
if len(v.Ranges[0].Intervals) != 52 {
t.Errorf("expected %v received %v", 52, len(v.Ranges[0].Intervals))
}
v, err = CalculateCandleDateRanges(et, ft, OneDay, 5)
v, err = CalculateCandleDateRanges(et, ft, OneWeek, 5)
if err != nil {
t.Error(err)
}
if len(v.Ranges) != 14756 {
t.Errorf("expected %v received %v", 14756, len(v.Ranges))
if len(v.Ranges) != 2108 {
t.Errorf("expected %v received %v", 2108, len(v.Ranges))
}
if len(v.Ranges[0].Intervals) != 5 {
t.Errorf("expected %v received %v", 5, len(v.Ranges[0].Intervals))
@@ -458,12 +467,13 @@ func TestCalculateCandleDateRanges(t *testing.T) {
}
lenRanges := len(v.Ranges) - 1
lenIntervals := len(v.Ranges[lenRanges].Intervals) - 1
if !v.Ranges[lenRanges].Intervals[lenIntervals].End.Equal(ft.Round(OneDay.Duration())) {
if !v.Ranges[lenRanges].Intervals[lenIntervals].End.Equal(ft.Round(OneWeek.Duration())) {
t.Errorf("expected %v received %v", ft.Round(OneDay.Duration()), v.Ranges[lenRanges].Intervals[lenIntervals].End)
}
}
func TestItem_SortCandlesByTimestamp(t *testing.T) {
t.Parallel()
var tempKline = Item{
Exchange: "testExchange",
Pair: currency.NewPair(currency.BTC, currency.USDT),
@@ -742,6 +752,7 @@ func TestLoadCSV(t *testing.T) {
}
func TestVerifyResultsHaveData(t *testing.T) {
t.Parallel()
tt2 := time.Now().Round(OneDay.Duration())
tt1 := time.Now().Add(-time.Hour * 24).Round(OneDay.Duration())
dateRanges, err := CalculateCandleDateRanges(tt1, tt2, OneDay, 0)
@@ -770,6 +781,7 @@ func TestVerifyResultsHaveData(t *testing.T) {
}
func TestDataSummary(t *testing.T) {
t.Parallel()
tt1 := time.Now().Add(-time.Hour * 24).Round(OneDay.Duration())
tt2 := time.Now().Round(OneDay.Duration())
tt3 := time.Now().Add(time.Hour * 24).Round(OneDay.Duration())
@@ -797,6 +809,7 @@ func TestDataSummary(t *testing.T) {
}
func TestHasDataAtDate(t *testing.T) {
t.Parallel()
tt2 := time.Now().Round(OneDay.Duration())
tt1 := time.Now().Add(-time.Hour * 24 * 30).Round(OneDay.Duration())
dateRanges, err := CalculateCandleDateRanges(tt1, tt2, OneDay, 0)
@@ -826,6 +839,7 @@ func TestHasDataAtDate(t *testing.T) {
}
func TestIntervalsPerYear(t *testing.T) {
t.Parallel()
i := OneYear
if i.IntervalsPerYear() != 1.0 {
t.Error("expected 1")

View File

@@ -128,10 +128,10 @@ func TestUpdateAccountInfo(t *testing.T) {
}
func TestWrapperGetOrderInfo(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip("skipping test: api keys not set")
}
t.Parallel()
_, err := k.GetOrderInfo("123", currency.Pair{}, asset.Futures)
if err != nil {
t.Error(err)
@@ -139,10 +139,10 @@ func TestWrapperGetOrderInfo(t *testing.T) {
}
func TestFuturesBatchOrder(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() || !canManipulateRealOrders {
t.Skip("skipping test: api keys not set or canManipulateRealOrders")
}
t.Parallel()
var data []PlaceBatchOrderData
var tempData PlaceBatchOrderData
tempData.PlaceOrderType = "cancel"
@@ -156,10 +156,10 @@ func TestFuturesBatchOrder(t *testing.T) {
}
func TestFuturesEditOrder(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() || !canManipulateRealOrders {
t.Skip("skipping test: api keys not set or canManipulateRealOrders")
}
t.Parallel()
_, err := k.FuturesEditOrder("test123", "", 5.2, 1, 0)
if err != nil {
t.Error(err)
@@ -167,10 +167,10 @@ func TestFuturesEditOrder(t *testing.T) {
}
func TestFuturesSendOrder(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() || !canManipulateRealOrders {
t.Skip("skipping test: api keys not set or canManipulateRealOrders")
}
t.Parallel()
cp, err := currency.NewPairFromString("PI_XBTUSD")
if err != nil {
t.Error(err)
@@ -182,10 +182,10 @@ func TestFuturesSendOrder(t *testing.T) {
}
func TestFuturesCancelOrder(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() || !canManipulateRealOrders {
t.Skip("skipping test: api keys not set or canManipulateRealOrders")
}
t.Parallel()
_, err := k.FuturesCancelOrder("test123", "")
if err != nil {
t.Error(err)
@@ -193,10 +193,10 @@ func TestFuturesCancelOrder(t *testing.T) {
}
func TestFuturesGetFills(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip("skipping test: api keys not set")
}
t.Parallel()
_, err := k.FuturesGetFills(time.Now().Add(-time.Hour * 24))
if err != nil {
t.Error(err)
@@ -204,10 +204,10 @@ func TestFuturesGetFills(t *testing.T) {
}
func TestFuturesTransfer(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip("skipping test: api keys not set")
}
t.Parallel()
_, err := k.FuturesTransfer("cash", "futures", "btc", 2)
if err != nil {
t.Error(err)
@@ -215,10 +215,10 @@ func TestFuturesTransfer(t *testing.T) {
}
func TestFuturesGetOpenPositions(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip("skipping test: api keys not set")
}
t.Parallel()
_, err := k.FuturesGetOpenPositions()
if err != nil {
t.Error(err)
@@ -226,10 +226,10 @@ func TestFuturesGetOpenPositions(t *testing.T) {
}
func TestFuturesNotifications(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip("skipping test: api keys not set")
}
t.Parallel()
_, err := k.FuturesNotifications()
if err != nil {
t.Error(err)
@@ -237,10 +237,10 @@ func TestFuturesNotifications(t *testing.T) {
}
func TestFuturesCancelAllOrders(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() || !canManipulateRealOrders {
t.Skip("skipping test: api keys not set or canManipulateRealOrders")
}
t.Parallel()
cp, err := currency.NewPairFromString("PI_XBTUSD")
if err != nil {
t.Error(err)
@@ -252,10 +252,10 @@ func TestFuturesCancelAllOrders(t *testing.T) {
}
func TestGetFuturesAccountData(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip("skipping test: api keys not set")
}
t.Parallel()
_, err := k.GetFuturesAccountData()
if err != nil {
t.Error(err)
@@ -263,10 +263,10 @@ func TestGetFuturesAccountData(t *testing.T) {
}
func TestFuturesCancelAllOrdersAfter(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() || !canManipulateRealOrders {
t.Skip("skipping test: api keys not set or canManipulateRealOrders")
}
t.Parallel()
_, err := k.FuturesCancelAllOrdersAfter(50)
if err != nil {
t.Error(err)
@@ -274,10 +274,10 @@ func TestFuturesCancelAllOrdersAfter(t *testing.T) {
}
func TestFuturesOpenOrders(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip("skipping test: api keys not set")
}
t.Parallel()
_, err := k.FuturesOpenOrders()
if err != nil {
t.Error(err)
@@ -285,10 +285,10 @@ func TestFuturesOpenOrders(t *testing.T) {
}
func TestFuturesRecentOrders(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip("skipping test: api keys not set")
}
t.Parallel()
cp, err := currency.NewPairFromString("PI_XBTUSD")
if err != nil {
t.Error(err)
@@ -300,10 +300,10 @@ func TestFuturesRecentOrders(t *testing.T) {
}
func TestFuturesWithdrawToSpotWallet(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() || !canManipulateRealOrders {
t.Skip("skipping test: api keys not set or canManipulateRealOrders")
}
t.Parallel()
_, err := k.FuturesWithdrawToSpotWallet("xbt", 5)
if err != nil {
t.Error(err)
@@ -311,10 +311,10 @@ func TestFuturesWithdrawToSpotWallet(t *testing.T) {
}
func TestFuturesGetTransfers(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip("skipping test: api keys not set")
}
t.Parallel()
_, err := k.FuturesGetTransfers(time.Now().Add(-time.Hour * 24))
if err != nil {
t.Error(err)
@@ -508,14 +508,6 @@ func TestGetTrades(t *testing.T) {
if err != nil {
t.Error("GetTrades() error", err)
}
cp2, err := currency.NewPairFromString("MADEUP")
if err != nil {
t.Error(err)
}
_, err = k.GetTrades(cp2)
if err == nil {
t.Error("expected error")
}
}
// TestGetSpread API endpoint test
@@ -680,6 +672,7 @@ func setFeeBuilder() *exchange.FeeBuilder {
// TestGetFeeByTypeOfflineTradeFee logic test
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
t.Parallel()
var feeBuilder = setFeeBuilder()
k.GetFeeByType(feeBuilder)
if !areTestAPIKeysSet() {
@@ -694,6 +687,7 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
}
func TestGetFee(t *testing.T) {
t.Parallel()
var feeBuilder = setFeeBuilder()
if areTestAPIKeysSet() {
@@ -766,6 +760,7 @@ func TestGetFee(t *testing.T) {
// TestFormatWithdrawPermissions logic test
func TestFormatWithdrawPermissions(t *testing.T) {
t.Parallel()
expectedResult := exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.WithdrawCryptoWith2FAText + " & " + exchange.AutoWithdrawFiatWithSetupText + " & " + exchange.WithdrawFiatWith2FAText
withdrawPermissions := k.FormatWithdrawPermissions()
if withdrawPermissions != expectedResult {
@@ -797,6 +792,7 @@ func TestGetActiveOrders(t *testing.T) {
// TestGetOrderHistory wrapper test
func TestGetOrderHistory(t *testing.T) {
t.Parallel()
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
AssetType: asset.Spot,
@@ -812,6 +808,7 @@ func TestGetOrderHistory(t *testing.T) {
// TestGetOrderHistory wrapper test
func TestGetOrderInfo(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -837,6 +834,7 @@ func areTestAPIKeysSet() bool {
// TestSubmitOrder wrapper test
func TestSubmitOrder(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -863,6 +861,7 @@ func TestSubmitOrder(t *testing.T) {
// TestCancelExchangeOrder wrapper test
func TestCancelExchangeOrder(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -883,6 +882,7 @@ func TestCancelExchangeOrder(t *testing.T) {
// TestCancelExchangeOrder wrapper test
func TestCancelBatchExchangeOrder(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -911,6 +911,7 @@ func TestCancelBatchExchangeOrder(t *testing.T) {
// TestCancelAllExchangeOrders wrapper test
func TestCancelAllExchangeOrders(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -930,6 +931,7 @@ func TestCancelAllExchangeOrders(t *testing.T) {
// TestGetAccountInfo wrapper test
func TestGetAccountInfo(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() {
_, err := k.UpdateAccountInfo(asset.Spot)
if err != nil {
@@ -945,6 +947,7 @@ func TestGetAccountInfo(t *testing.T) {
}
func TestUpdateFuturesAccountInfo(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip("API keys not set. Skipping the test")
}
@@ -957,6 +960,7 @@ func TestUpdateFuturesAccountInfo(t *testing.T) {
// TestModifyOrder wrapper test
func TestModifyOrder(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -968,6 +972,7 @@ func TestModifyOrder(t *testing.T) {
// TestWithdraw wrapper test
func TestWithdraw(t *testing.T) {
t.Parallel()
withdrawCryptoRequest := withdraw.Request{
Exchange: k.Name,
Crypto: withdraw.CryptoRequest{
@@ -994,6 +999,7 @@ func TestWithdraw(t *testing.T) {
// TestWithdrawFiat wrapper test
func TestWithdrawFiat(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -1016,6 +1022,7 @@ func TestWithdrawFiat(t *testing.T) {
// TestWithdrawInternationalBank wrapper test
func TestWithdrawInternationalBank(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -1038,6 +1045,7 @@ func TestWithdrawInternationalBank(t *testing.T) {
// TestGetDepositAddress wrapper test
func TestGetDepositAddress(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() {
_, err := k.GetDepositAddress(currency.BTC, "")
if err != nil {
@@ -1053,6 +1061,7 @@ func TestGetDepositAddress(t *testing.T) {
// TestWithdrawStatus wrapper test
func TestWithdrawStatus(t *testing.T) {
t.Parallel()
if areTestAPIKeysSet() {
_, err := k.WithdrawStatus(currency.BTC, "")
if err != nil {
@@ -1068,6 +1077,7 @@ func TestWithdrawStatus(t *testing.T) {
// TestWithdrawCancel wrapper test
func TestWithdrawCancel(t *testing.T) {
t.Parallel()
_, err := k.WithdrawCancel(currency.BTC, "")
if areTestAPIKeysSet() && err == nil {
t.Error("WithdrawCancel() error cannot be nil")
@@ -1166,6 +1176,7 @@ func TestWsCancelAllOrders(t *testing.T) {
}
func TestWsPong(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"event": "pong",
"reqid": 42
@@ -1177,6 +1188,7 @@ func TestWsPong(t *testing.T) {
}
func TestWsSystemStatus(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"connectionID": 8628615390848610000,
"event": "systemStatus",
@@ -1190,6 +1202,7 @@ func TestWsSystemStatus(t *testing.T) {
}
func TestWsSubscriptionStatus(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 10001,
"channelName": "ticker",
@@ -1251,6 +1264,7 @@ func TestWsSubscriptionStatus(t *testing.T) {
}
func TestWsTicker(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 1337,
"channelName": "ticker",
@@ -1317,6 +1331,7 @@ func TestWsTicker(t *testing.T) {
}
func TestWsOHLC(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 13337,
"channelName": "ohlc",
@@ -1354,6 +1369,7 @@ func TestWsOHLC(t *testing.T) {
}
func TestWsTrade(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 133337,
"channelName": "trade",
@@ -1398,6 +1414,7 @@ func TestWsTrade(t *testing.T) {
}
func TestWsSpread(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 1333337,
"channelName": "spread",
@@ -1431,6 +1448,7 @@ func TestWsSpread(t *testing.T) {
}
func TestWsOrdrbook(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"channelID": 13333337,
"channelName": "book",
@@ -1606,6 +1624,7 @@ func TestWsOrdrbook(t *testing.T) {
}
func TestWsOwnTrades(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`[
[
{
@@ -1678,6 +1697,7 @@ func TestWsOwnTrades(t *testing.T) {
}
func TestWsOpenOrders(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`[
[
{
@@ -1825,6 +1845,7 @@ func TestWsOpenOrders(t *testing.T) {
}
func TestWsAddOrderJSON(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"descr": "buy 0.01770000 XBTUSD @ limit 4000",
"event": "addOrderStatus",
@@ -1838,6 +1859,7 @@ func TestWsAddOrderJSON(t *testing.T) {
}
func TestWsCancelOrderJSON(t *testing.T) {
t.Parallel()
pressXToJSON := []byte(`{
"event": "cancelOrderStatus",
"status": "ok"
@@ -1849,6 +1871,7 @@ func TestWsCancelOrderJSON(t *testing.T) {
}
func TestParseTime(t *testing.T) {
t.Parallel()
// Test REST example
r := convert.TimeFromUnixTimestampDecimal(1373750306.9819).UTC()
if r.Year() != 2013 ||
@@ -1867,11 +1890,12 @@ func TestParseTime(t *testing.T) {
}
func TestGetHistoricCandles(t *testing.T) {
t.Parallel()
currencyPair, err := currency.NewPairFromString("XBT-USD")
if err != nil {
t.Fatal(err)
}
_, err = k.GetHistoricCandles(currencyPair, asset.Spot, time.Now().AddDate(0, 0, -1), time.Now(), kline.OneMin)
_, err = k.GetHistoricCandles(currencyPair, asset.Spot, time.Now(), time.Now().Add(-time.Minute*3), kline.OneMin)
if err != nil {
t.Fatal(err)
}
@@ -1883,11 +1907,12 @@ func TestGetHistoricCandles(t *testing.T) {
}
func TestGetHistoricCandlesExtended(t *testing.T) {
t.Parallel()
currencyPair, err := currency.NewPairFromString("XBT-USD")
if err != nil {
t.Fatal(err)
}
_, err = k.GetHistoricCandlesExtended(currencyPair, asset.Spot, time.Now().AddDate(0, -6, 0), time.Now(), kline.OneDay)
_, err = k.GetHistoricCandlesExtended(currencyPair, asset.Spot, time.Now().Add(-time.Hour*48), time.Now(), kline.OneDay)
if err != nil {
t.Fatal(err)
}
@@ -1899,6 +1924,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) {
}
func Test_FormatExchangeKlineInterval(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
interval kline.Interval
@@ -1931,7 +1957,7 @@ func Test_FormatExchangeKlineInterval(t *testing.T) {
func TestGetRecentTrades(t *testing.T) {
t.Parallel()
currencyPair, err := currency.NewPairFromString("XBTUSD")
currencyPair, err := currency.NewPairFromString("BCHEUR")
if err != nil {
t.Fatal(err)
}
@@ -1983,6 +2009,7 @@ var testOb = orderbook.Base{
const krakenAPIDocChecksum = 974947235
func TestChecksumCalculation(t *testing.T) {
t.Parallel()
expected := "5005"
if v := trim("0.05005"); v != expected {
t.Fatalf("expected %s but received %s", expected, v)

View File

@@ -58,9 +58,12 @@ const (
// orderbookMutex Ensures if two entries arrive at once, only one can be
// processed at a time
var subscriptionChannelPair []WebsocketChannelData
var authToken string
var pingRequest = WebsocketBaseEventRequest{Event: stream.Ping}
var (
subscriptionChannelPair []WebsocketChannelData
authToken string
pingRequest = WebsocketBaseEventRequest{Event: stream.Ping}
m sync.Mutex
)
// Channels require a topic and a currency
// Format [[ticker,but-t4u],[orderbook,nce-btt]]
@@ -625,6 +628,8 @@ func (k *Kraken) addNewSubscriptionChannelData(response *wsSubscription) {
return
}
}
m.Lock()
defer m.Unlock()
subscriptionChannelPair = append(subscriptionChannelPair, WebsocketChannelData{
Subscription: response.Subscription.Name,
Pair: fPair,
@@ -634,6 +639,8 @@ func (k *Kraken) addNewSubscriptionChannelData(response *wsSubscription) {
// getSubscriptionChannelData retrieves WebsocketChannelData based on response ID
func getSubscriptionChannelData(id int64) (WebsocketChannelData, error) {
m.Lock()
defer m.Unlock()
for i := range subscriptionChannelPair {
if subscriptionChannelPair[i].ChannelID == nil {
continue

View File

@@ -492,7 +492,7 @@ func TestGetHistoricTrades(t *testing.T) {
if err != nil {
t.Fatal(err)
}
_, err = l.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Hour*24), time.Now())
_, err = l.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now())
if err != nil && err != common.ErrFunctionNotSupported {
t.Error(err)
}

View File

@@ -427,7 +427,7 @@ func TestGetHistoricCandles(t *testing.T) {
func TestGetHistoricCandlesExtended(t *testing.T) {
t.Parallel()
startTime := time.Now().Add(-time.Hour)
startTime := time.Now().Add(-time.Minute * 2)
end := time.Now()
pair, err := currency.NewPairFromString("eth_btc")
if err != nil {

View File

@@ -356,7 +356,7 @@ func (l *Lbank) GetWithdrawalsHistory(c currency.Code) (resp []exchange.Withdraw
// GetRecentTrades returns the most recent trades for a currency and asset
func (l *Lbank) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) {
return l.GetHistoricTrades(p, assetType, time.Now().Add(-time.Hour), time.Now())
return l.GetHistoricTrades(p, assetType, time.Now().Add(-time.Minute*15), time.Now())
}
// GetHistoricTrades returns historic trade data within the timeframe provided

View File

@@ -823,7 +823,6 @@ func TestOrderBookUpdateChecksumCalculator(t *testing.T) {
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Second)
err = o.WsProcessOrderBook([]byte(update))
if err != nil {
t.Error(err)
@@ -841,7 +840,6 @@ func TestOrderBookUpdateChecksumCalculatorWith8DecimalPlaces(t *testing.T) {
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Second)
err = o.WsProcessOrderBook([]byte(update))
if err != nil {
t.Error(err)

View File

@@ -1647,7 +1647,6 @@ func TestOrderBookUpdateChecksumCalculator(t *testing.T) {
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Second)
err = o.WsHandleData([]byte(update))
if err != nil {
t.Error(err)
@@ -1662,7 +1661,6 @@ func TestOrderBookUpdateChecksumCalculatorWith8DecimalPlaces(t *testing.T) {
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Second)
err = o.WsHandleData([]byte(update))
if err != nil {
t.Error(err)

View File

@@ -423,6 +423,7 @@ func TestOrderbookLastUpdateID(t *testing.T) {
// TestRunUpdateWithoutSnapshot logic test
func TestRunUpdateWithoutSnapshot(t *testing.T) {
t.Parallel()
var holder Orderbook
var snapShot1 orderbook.Base
asks := []orderbook.Item{
@@ -451,6 +452,7 @@ func TestRunUpdateWithoutSnapshot(t *testing.T) {
// TestRunUpdateWithoutAnyUpdates logic test
func TestRunUpdateWithoutAnyUpdates(t *testing.T) {
t.Parallel()
var obl Orderbook
var snapShot1 orderbook.Base
snapShot1.Asks = []orderbook.Item{}
@@ -472,6 +474,7 @@ func TestRunUpdateWithoutAnyUpdates(t *testing.T) {
// TestRunSnapshotWithNoData logic test
func TestRunSnapshotWithNoData(t *testing.T) {
t.Parallel()
var obl Orderbook
obl.ob = make(map[currency.Code]map[currency.Code]map[asset.Item]*orderbookHolder)
obl.dataHandler = make(chan interface{}, 1)
@@ -488,6 +491,7 @@ func TestRunSnapshotWithNoData(t *testing.T) {
// TestLoadSnapshot logic test
func TestLoadSnapshot(t *testing.T) {
t.Parallel()
var obl Orderbook
obl.dataHandler = make(chan interface{}, 100)
obl.ob = make(map[currency.Code]map[currency.Code]map[asset.Item]*orderbookHolder)
@@ -509,8 +513,8 @@ func TestLoadSnapshot(t *testing.T) {
}
}
// TestFlushbuffer logic test
func TestFlushbuffer(t *testing.T) {
// TestFlushBuffer logic test
func TestFlushBuffer(t *testing.T) {
obl, _, _, err := createSnapshot()
if err != nil {
t.Fatal(err)
@@ -526,6 +530,7 @@ func TestFlushbuffer(t *testing.T) {
// TestInsertingSnapShots logic test
func TestInsertingSnapShots(t *testing.T) {
t.Parallel()
var holder Orderbook
holder.dataHandler = make(chan interface{}, 100)
holder.ob = make(map[currency.Code]map[currency.Code]map[asset.Item]*orderbookHolder)
@@ -705,6 +710,7 @@ func TestGetOrderbook(t *testing.T) {
}
func TestSetup(t *testing.T) {
t.Parallel()
w := Orderbook{}
err := w.Setup(0, false, false, false, false, true, "", nil)
if !errors.Is(err, errUnsetExchangeName) {
@@ -736,6 +742,7 @@ func TestSetup(t *testing.T) {
}
func TestValidate(t *testing.T) {
t.Parallel()
w := Orderbook{}
err := w.validate(nil)
if !errors.Is(err, errUpdateIsNil) {
@@ -749,6 +756,7 @@ func TestValidate(t *testing.T) {
}
func TestEnsureMultipleUpdatesViaPrice(t *testing.T) {
t.Parallel()
holder, _, _, err := createSnapshot()
if err != nil {
t.Error(err)
@@ -782,6 +790,7 @@ func deploySliceOrdered(size int) orderbook.Items {
}
func TestUpdateByIDAndAction(t *testing.T) {
t.Parallel()
holder := orderbookHolder{}
asks := deploySliceOrdered(100)
@@ -990,6 +999,7 @@ func TestUpdateByIDAndAction(t *testing.T) {
}
func TestFlushOrderbook(t *testing.T) {
t.Parallel()
w := &Orderbook{}
err := w.Setup(5, false, false, false, false, false, "test", make(chan interface{}, 2))
if err != nil {

View File

@@ -6,6 +6,7 @@ import (
)
func TestMatch(t *testing.T) {
t.Parallel()
bm := &Match{}
if bm.Incoming("wow") {
t.Fatal("Should not have matched")

View File

@@ -87,6 +87,7 @@ func (d *dodgyConnection) Connect() error {
}
func TestSetup(t *testing.T) {
t.Parallel()
var w *Websocket
err := w.Setup(nil)
if err == nil {
@@ -164,7 +165,7 @@ func TestTrafficMonitorTimeout(t *testing.T) {
if err != nil {
t.Fatal(err)
}
ws.trafficTimeout = time.Millisecond
ws.trafficTimeout = time.Second * 2
ws.ShutdownC = make(chan struct{})
ws.trafficMonitor()
if !ws.IsTrafficMonitorRunning() {
@@ -187,6 +188,7 @@ func TestTrafficMonitorTimeout(t *testing.T) {
}
func TestIsDisconnectionError(t *testing.T) {
t.Parallel()
isADisconnectionError := isDisconnectionError(errors.New("errorText"))
if isADisconnectionError {
t.Error("Its not")
@@ -215,6 +217,7 @@ func TestIsDisconnectionError(t *testing.T) {
}
func TestConnectionMessageErrors(t *testing.T) {
t.Parallel()
var wsWrong = &Websocket{}
err := wsWrong.Connect()
if err == nil {
@@ -283,6 +286,7 @@ outer:
}
func TestWebsocket(t *testing.T) {
t.Parallel()
wsInit := Websocket{}
err := wsInit.Setup(&WebsocketSetup{
ExchangeName: "test",
@@ -440,6 +444,7 @@ func TestWebsocket(t *testing.T) {
// TestSubscribe logic test
func TestSubscribeUnsubscribe(t *testing.T) {
t.Parallel()
ws := *New()
err := ws.Setup(defaultSetup)
if err != nil {
@@ -498,6 +503,7 @@ func TestSubscribeUnsubscribe(t *testing.T) {
}
func TestResubscribe(t *testing.T) {
t.Parallel()
ws := *New()
err := ws.Setup(defaultSetup)
if err != nil {
@@ -534,6 +540,7 @@ func TestResubscribe(t *testing.T) {
// TestConnectionMonitorNoConnection logic test
func TestConnectionMonitorNoConnection(t *testing.T) {
t.Parallel()
ws := *New()
ws.DataHandler = make(chan interface{}, 1)
ws.ShutdownC = make(chan struct{}, 1)
@@ -567,6 +574,7 @@ func TestConnectionMonitorNoConnection(t *testing.T) {
// TestSliceCopyDoesntImpactBoth logic test
func TestGetSubscriptions(t *testing.T) {
t.Parallel()
w := Websocket{
subscriptions: []ChannelSubscription{
{
@@ -581,6 +589,7 @@ func TestGetSubscriptions(t *testing.T) {
// TestSetCanUseAuthenticatedEndpoints logic test
func TestSetCanUseAuthenticatedEndpoints(t *testing.T) {
t.Parallel()
ws := *New()
result := ws.CanUseAuthenticatedEndpoints()
if result {
@@ -595,6 +604,7 @@ func TestSetCanUseAuthenticatedEndpoints(t *testing.T) {
// TestDial logic test
func TestDial(t *testing.T) {
t.Parallel()
var testCases = []testStruct{
{Error: nil,
WC: WebsocketConnection{
@@ -642,6 +652,7 @@ func TestDial(t *testing.T) {
// TestSendMessage logic test
func TestSendMessage(t *testing.T) {
t.Parallel()
var testCases = []testStruct{
{Error: nil, WC: WebsocketConnection{
ExchangeName: "test1",
@@ -696,6 +707,7 @@ func TestSendMessage(t *testing.T) {
// TestSendMessageWithResponse logic test
func TestSendMessageWithResponse(t *testing.T) {
t.Parallel()
wc := &WebsocketConnection{
Verbose: true,
URL: "wss://ws.kraken.com",
@@ -757,6 +769,7 @@ func readMessages(wc *WebsocketConnection, t *testing.T) {
// TestSetupPingHandler logic test
func TestSetupPingHandler(t *testing.T) {
t.Parallel()
wc := &WebsocketConnection{
URL: websocketTestURL,
ResponseMaxLimit: time.Second * 5,
@@ -800,6 +813,7 @@ func TestSetupPingHandler(t *testing.T) {
// TestParseBinaryResponse logic test
func TestParseBinaryResponse(t *testing.T) {
t.Parallel()
wc := &WebsocketConnection{
URL: websocketTestURL,
ResponseMaxLimit: time.Second * 5,
@@ -849,6 +863,7 @@ func TestParseBinaryResponse(t *testing.T) {
// TestCanUseAuthenticatedWebsocketForWrapper logic test
func TestCanUseAuthenticatedWebsocketForWrapper(t *testing.T) {
t.Parallel()
ws := &Websocket{}
resp := ws.CanUseAuthenticatedWebsocketForWrapper()
if resp {
@@ -867,6 +882,7 @@ func TestCanUseAuthenticatedWebsocketForWrapper(t *testing.T) {
}
func TestGenerateMessageID(t *testing.T) {
t.Parallel()
wc := WebsocketConnection{}
var id int64
for i := 0; i < 10; i++ {
@@ -927,6 +943,7 @@ func TestCheckWebsocketURL(t *testing.T) {
}
func TestGetChannelDifference(t *testing.T) {
t.Parallel()
web := Websocket{}
newChans := []ChannelSubscription{
@@ -1022,6 +1039,7 @@ func (g *GenSubs) UNSUBME(unsubs []ChannelSubscription) error {
func connect() error { return nil }
func TestFlushChannels(t *testing.T) {
t.Parallel()
// Enabled pairs/setup system
newgen := GenSubs{EnabledPairs: []currency.Pair{
currency.NewPair(currency.BTC, currency.AUD),
@@ -1143,6 +1161,7 @@ func TestFlushChannels(t *testing.T) {
}
func TestDisable(t *testing.T) {
t.Parallel()
web := Websocket{
enabled: true,
connected: true,
@@ -1159,6 +1178,7 @@ func TestDisable(t *testing.T) {
}
func TestEnable(t *testing.T) {
t.Parallel()
web := Websocket{
connector: connect,
Wg: new(sync.WaitGroup),
@@ -1178,6 +1198,7 @@ func TestEnable(t *testing.T) {
}
func TestSetupNewConnection(t *testing.T) {
t.Parallel()
var nonsenseWebsock *Websocket
err := nonsenseWebsock.SetupNewConnection(ConnectionSetup{URL: "urlstring"})
if err == nil {
@@ -1232,6 +1253,7 @@ func TestSetupNewConnection(t *testing.T) {
}
func TestWebsocketConnectionShutdown(t *testing.T) {
t.Parallel()
wc := WebsocketConnection{}
err := wc.Shutdown()
if err != nil {

View File

@@ -203,17 +203,16 @@ func TestShutdown(t *testing.T) {
t.Parallel()
var p Processor
p.mutex.Lock()
p.bufferProcessorInterval = time.Second
p.bufferProcessorInterval = time.Millisecond
p.mutex.Unlock()
var wg sync.WaitGroup
wg.Add(1)
go p.Run(&wg)
wg.Wait()
time.Sleep(time.Millisecond)
if atomic.LoadInt32(&p.started) != 1 {
t.Error("expected it to start running")
}
time.Sleep(time.Second * 2)
time.Sleep(time.Millisecond * 20)
if atomic.LoadInt32(&p.started) != 0 {
t.Error("expected it to stop running")
}

View File

@@ -93,7 +93,6 @@ func TestVMLoad1s(t *testing.T) {
}
testVM.CompileAndRun()
time.Sleep(5000)
err = testVM.Shutdown()
if err != nil {
if !errors.Is(err, ErrNoVMLoaded) {

View File

@@ -8,14 +8,35 @@ import (
"github.com/thrasher-corp/gocryptotrader/currency"
)
// SetAccounts safely overwrites bank account slice
func SetAccounts(accs ...Account) {
m.Lock()
defer m.Unlock()
accounts = accs
}
// AppendAccounts safely adds to bank account slice
func AppendAccounts(accs ...Account) {
m.Lock()
defer m.Unlock()
accountRange:
for j := range accs {
for i := range accounts {
if accounts[i].AccountNumber == accs[j].AccountNumber {
continue accountRange
}
}
accounts = append(accounts, accs[j])
}
}
// GetBankAccountByID Returns a bank account based on its ID
func GetBankAccountByID(id string) (*Account, error) {
m.Lock()
defer m.Unlock()
for x := range Accounts {
if strings.EqualFold(Accounts[x].ID, id) {
return &Accounts[x], nil
for x := range accounts {
if strings.EqualFold(accounts[x].ID, id) {
return &accounts[x], nil
}
}
return nil, fmt.Errorf(ErrBankAccountNotFound, id)
@@ -83,7 +104,7 @@ func (b *Account) ValidateForWithdrawal(exchange string, cur currency.Code) (err
if cur.Upper() == currency.AUD {
if b.BSBNumber == "" {
err = append(err, ErrBSBRequiredforAUD)
err = append(err, ErrBSBRequiredForAUD)
}
} else {
if b.IBAN == "" && b.SWIFTCode == "" {

View File

@@ -8,53 +8,51 @@ import (
)
var (
testBankAccounts = []Account{
{
Enabled: true,
ID: "valid-test-bank-01",
BankName: "Test Bank",
BankAddress: "42 Bank Street",
BankPostalCode: "13337",
BankPostalCity: "Satoshiville",
BankCountry: "Japan",
AccountName: "Satoshi Nakamoto",
AccountNumber: "0234",
SWIFTCode: "91272837",
BSBNumber: "123456",
IBAN: "98218738671897",
SupportedCurrencies: "AUD,USD",
SupportedExchanges: "test-exchange",
},
{
Enabled: false,
ID: "invalid-test-bank-01",
BankName: "",
BankAddress: "",
BankPostalCode: "",
BankPostalCity: "",
BankCountry: "",
AccountName: "",
AccountNumber: "",
SWIFTCode: "",
BSBNumber: "",
IBAN: "",
SupportedCurrencies: "",
SupportedExchanges: "",
},
validAccount = Account{
Enabled: true,
ID: "valid-test-bank-01",
BankName: "Test Bank",
BankAddress: "42 Bank Street",
BankPostalCode: "13337",
BankPostalCity: "Satoshiville",
BankCountry: "Japan",
AccountName: "Satoshi Nakamoto",
AccountNumber: "0234",
SWIFTCode: "91272837",
BSBNumber: "123456",
IBAN: "98218738671897",
SupportedCurrencies: "AUD,USD",
SupportedExchanges: "test-exchange",
}
invalidAccount = Account{
Enabled: false,
ID: "invalid-test-bank-01",
BankName: "",
BankAddress: "",
BankPostalCode: "",
BankPostalCity: "",
BankCountry: "",
AccountName: "",
AccountNumber: "",
SWIFTCode: "",
BSBNumber: "",
IBAN: "",
SupportedCurrencies: "",
SupportedExchanges: "",
}
)
func TestMain(m *testing.M) {
Accounts = append(Accounts, testBankAccounts...)
os.Exit(m.Run())
}
func TestGetBankAccountByID(t *testing.T) {
t.Parallel()
SetAccounts(validAccount, invalidAccount)
_, err := GetBankAccountByID("valid-test-bank-01")
if err != nil {
t.Error(err)
}
_, err = GetBankAccountByID("invalid-test-")
if err == nil {
t.Error("error expected for invalid account received nil")
@@ -62,29 +60,25 @@ func TestGetBankAccountByID(t *testing.T) {
}
func TestAccount_Validate(t *testing.T) {
valid, err := GetBankAccountByID("valid-test-bank-01")
if err != nil {
t.Fatal(err)
t.Parallel()
testBankAccounts := []Account{
validAccount, invalidAccount,
}
if err = valid.Validate(); err != nil {
t.Error(err)
}
invalid := testBankAccounts[1]
if err = invalid.Validate(); err == nil {
if err := invalid.Validate(); err == nil {
t.Error(err)
}
invalid = testBankAccounts[0]
invalid.SupportedCurrencies = "AUD"
invalid.BSBNumber = ""
if err = invalid.Validate(); err == nil {
if err := invalid.Validate(); err == nil {
t.Error("Expected error when Currency is AUD but no BSB set")
}
invalid = testBankAccounts[0]
invalid.SupportedExchanges = ""
if err = invalid.Validate(); err != nil {
if err := invalid.Validate(); err != nil {
t.Error("Expected error when Currency is AUD but no BSB set")
}
if invalid.SupportedExchanges != "ALL" {
@@ -95,53 +89,73 @@ func TestAccount_Validate(t *testing.T) {
invalid.SWIFTCode = ""
invalid.IBAN = ""
invalid.SupportedCurrencies = "USD"
if err = invalid.Validate(); err == nil {
if err := invalid.Validate(); err == nil {
t.Error("Expected error when no Swift/IBAN set")
}
}
func TestAccount_ValidateForWithdrawal(t *testing.T) {
v, err := GetBankAccountByID("valid-test-bank-01")
if err != nil {
t.Fatal(err)
}
errWith := v.ValidateForWithdrawal("test-exchange", currency.AUD)
t.Parallel()
acc := validAccount
errWith := acc.ValidateForWithdrawal("test-exchange", currency.AUD)
if errWith != nil {
t.Fatal(errWith)
}
v.BSBNumber = ""
errWith = v.ValidateForWithdrawal("test-exchange", currency.AUD)
acc.BSBNumber = ""
errWith = acc.ValidateForWithdrawal("test-exchange", currency.AUD)
if errWith != nil {
if errWith[0] != ErrBSBRequiredforAUD {
if errWith[0] != ErrBSBRequiredForAUD {
t.Fatal(errWith)
}
}
v.SWIFTCode = ""
v.IBAN = ""
errWith = v.ValidateForWithdrawal("test-exchange", currency.USD)
acc.SWIFTCode = ""
acc.IBAN = ""
errWith = acc.ValidateForWithdrawal("test-exchange", currency.USD)
if errWith != nil {
if errWith[0] != ErrIBANSwiftNotSet {
t.Fatal(errWith)
}
}
errWith = v.ValidateForWithdrawal("test-exchange-nope", currency.AUD)
errWith = acc.ValidateForWithdrawal("test-exchange-nope", currency.AUD)
if errWith != nil {
if errWith[0] != "Exchange test-exchange-nope not supported by bank account" {
t.Fatal(errWith)
}
}
v.AccountNumber = ""
errWith = v.ValidateForWithdrawal("test-exchange", currency.AUD)
acc.AccountNumber = ""
errWith = acc.ValidateForWithdrawal("test-exchange", currency.AUD)
if errWith != nil {
if errWith[0] != ErrAccountCannotBeEmpty {
t.Fatal(errWith)
}
}
v.Enabled = false
errWith = v.ValidateForWithdrawal("test-exchange", currency.AUD)
acc.Enabled = false
errWith = acc.ValidateForWithdrawal("test-exchange", currency.AUD)
if errWith != nil {
if errWith[0] != ErrBankAccountDisabled {
t.Fatal(errWith)
}
}
}
func TestSetAccounts(t *testing.T) {
SetAccounts()
if len(accounts) != 0 {
t.Error("expected 0")
}
SetAccounts(validAccount, invalidAccount)
if len(accounts) != 2 {
t.Error("expected 2")
}
}
func TestAppendAccounts(t *testing.T) {
SetAccounts()
if len(accounts) != 0 {
t.Error("expected 0")
}
AppendAccounts(validAccount, invalidAccount)
if len(accounts) != 2 {
t.Error("expected 2")
}
}

View File

@@ -7,14 +7,12 @@ import (
const (
// ErrBankAccountNotFound message to return when bank account was not found
ErrBankAccountNotFound = "bank account ID: %v not found"
// ErrAccountCannotBeNil message to return when bank account is nil
ErrAccountCannotBeNil = "Account cannot be nil"
// ErrAccountCannotBeEmpty message to return when bank account number is empty
ErrAccountCannotBeEmpty = "Bank Account Number cannot be empty"
// ErrBankAccountDisabled message to return when bank account is disabled
ErrBankAccountDisabled = "Bank Account is disabled"
// ErrBSBRequiredforAUD message to return when currency is AUD but no bsb is set
ErrBSBRequiredforAUD = "BSB must be set for AUD values"
// ErrBSBRequiredForAUD message to return when currency is AUD but no bsb is set
ErrBSBRequiredForAUD = "BSB must be set for AUD values"
// ErrIBANSwiftNotSet message to return when no iban or swift value set
ErrIBANSwiftNotSet = "IBAN/SWIFT values not set"
// ErrCurrencyNotSupportedByAccount message to return when the requested
@@ -22,6 +20,11 @@ const (
ErrCurrencyNotSupportedByAccount = "requested currency is not supported by account"
)
var (
accounts []Account
m sync.Mutex
)
// Account holds differing bank account details by supported funding
// currency
type Account struct {
@@ -41,7 +44,3 @@ type Account struct {
SupportedCurrencies string `json:"supportedCurrencies"`
SupportedExchanges string `json:"supportedExchanges,omitempty"`
}
// Accounts holds all bank account details
var Accounts []Account
var m = &sync.Mutex{}

View File

@@ -3,7 +3,6 @@ package portfolio
import (
"errors"
"testing"
"time"
"github.com/thrasher-corp/gocryptotrader/core"
"github.com/thrasher-corp/gocryptotrader/currency"
@@ -14,6 +13,7 @@ const (
)
func TestGetEthereumBalance(t *testing.T) {
t.Parallel()
b := Base{}
address := "0xb794f5ea0ba39494ce839613fffba74279579268"
nonsenseAddress := "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
@@ -34,6 +34,7 @@ func TestGetEthereumBalance(t *testing.T) {
}
func TestGetCryptoIDBalance(t *testing.T) {
t.Parallel()
b := Base{}
ltcAddress := "LX2LMYXtuv5tiYEMztSSoEZcafFPYJFRK1"
_, err := b.GetCryptoIDAddress(ltcAddress, currency.LTC)
@@ -43,6 +44,7 @@ func TestGetCryptoIDBalance(t *testing.T) {
}
func TestGetAddressBalance(t *testing.T) {
t.Parallel()
ltcAddress := "LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL"
ltc := currency.LTC
description := "Description of Wallet"
@@ -75,6 +77,7 @@ func TestGetAddressBalance(t *testing.T) {
}
func TestGetRippleBalance(t *testing.T) {
t.Parallel()
b := Base{}
nonsenseAddress := "Wigwham"
_, err := b.GetRippleBalance(nonsenseAddress)
@@ -90,6 +93,7 @@ func TestGetRippleBalance(t *testing.T) {
}
func TestExchangeExists(t *testing.T) {
t.Parallel()
newBase := Base{}
err := newBase.AddAddress("someaddress",
currency.LTC.String(),
@@ -108,6 +112,7 @@ func TestExchangeExists(t *testing.T) {
}
func TestAddressExists(t *testing.T) {
t.Parallel()
newBase := Base{}
err := newBase.AddAddress("someaddress",
currency.LTC.String(),
@@ -126,6 +131,7 @@ func TestAddressExists(t *testing.T) {
}
func TestExchangeAddressExists(t *testing.T) {
t.Parallel()
newBase := Base{}
err := newBase.AddAddress("someaddress",
currency.LTC.String(),
@@ -144,6 +150,7 @@ func TestExchangeAddressExists(t *testing.T) {
}
func TestAddExchangeAddress(t *testing.T) {
t.Parallel()
newBase := Base{}
newBase.AddExchangeAddress("OKEX", currency.BTC, 100)
newBase.AddExchangeAddress("OKEX", currency.BTC, 200)
@@ -154,6 +161,7 @@ func TestAddExchangeAddress(t *testing.T) {
}
func TestUpdateAddressBalance(t *testing.T) {
t.Parallel()
newBase := Base{}
err := newBase.AddAddress("someaddress",
currency.LTC.String(),
@@ -173,6 +181,7 @@ func TestUpdateAddressBalance(t *testing.T) {
}
func TestRemoveAddress(t *testing.T) {
t.Parallel()
var newBase Base
if err := newBase.RemoveAddress("", "MEOW", currency.LTC); err == nil {
t.Error("invalid address should throw an error")
@@ -210,6 +219,7 @@ func TestRemoveAddress(t *testing.T) {
}
func TestRemoveExchangeAddress(t *testing.T) {
t.Parallel()
newBase := Base{}
exchangeName := "BallerExchange"
coinType := currency.LTC
@@ -227,6 +237,7 @@ func TestRemoveExchangeAddress(t *testing.T) {
}
func TestUpdateExchangeAddressBalance(t *testing.T) {
t.Parallel()
newBase := Base{}
newBase.AddExchangeAddress("someaddress", currency.LTC, 0.02)
b := Base{}
@@ -240,6 +251,7 @@ func TestUpdateExchangeAddressBalance(t *testing.T) {
}
func TestAddAddress(t *testing.T) {
t.Parallel()
var newBase Base
if err := newBase.AddAddress("", "MEOW", currency.LTC, 1); err == nil {
t.Error("invalid address should throw an error")
@@ -298,22 +310,9 @@ func TestAddAddress(t *testing.T) {
}
func TestUpdatePortfolio(t *testing.T) {
t.Parallel()
newBase := Base{}
err := newBase.AddAddress("someaddress",
currency.LTC.String(),
currency.NewCode("LTCWALLETTEST"),
0.02)
if err != nil {
t.Fatal(err)
}
err = newBase.UpdatePortfolio(
[]string{"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL"},
currency.LTC)
if err != nil {
t.Error("UpdatePortfolio error", err)
}
err = newBase.UpdatePortfolio([]string{"Testy"}, currency.LTC)
err := newBase.UpdatePortfolio([]string{"Testy"}, currency.LTC)
if err == nil {
t.Error("UpdatePortfolio error cannot be nil")
}
@@ -326,22 +325,19 @@ func TestUpdatePortfolio(t *testing.T) {
t.Error("UpdatePortfolio error", err)
}
err = newBase.UpdatePortfolio(
[]string{"LdP8Qox1VAhCzLJNqrr74YovaWYyNBUWvL", "Testy"}, currency.LTC,
[]string{"Testy"}, currency.LTC,
)
if err == nil {
t.Error("UpdatePortfolio error cannot be nil")
}
time.Sleep(time.Second * 5)
err = newBase.UpdatePortfolio([]string{
"0xb794f5ea0ba39494ce839613fffba74279579268",
"0xe853c56864a2ebe4576a807d26fdc4a0ada51919"},
"0xb794f5ea0ba39494ce839613fffba74279579268"},
currency.ETH)
if err != nil {
t.Error(err)
}
err = newBase.UpdatePortfolio([]string{
"0xb794f5ea0ba39494ce839613fffba74279579268",
"TESTY"},
currency.ETH)
if err == nil {
@@ -363,7 +359,6 @@ func TestUpdatePortfolio(t *testing.T) {
}
err = newBase.UpdatePortfolio([]string{
"r962iS5subzbVeXZN8MTzyEuuaQKo5qksh",
"TESTY"},
currency.XRP)
if err == nil {
@@ -372,6 +367,7 @@ func TestUpdatePortfolio(t *testing.T) {
}
func TestGetPortfolioByExchange(t *testing.T) {
t.Parallel()
newBase := Base{}
newBase.AddExchangeAddress("OKEX", currency.LTC, 0.07)
newBase.AddExchangeAddress("Bitfinex", currency.LTC, 0.05)
@@ -401,6 +397,7 @@ func TestGetPortfolioByExchange(t *testing.T) {
}
func TestGetExchangePortfolio(t *testing.T) {
t.Parallel()
newBase := Base{}
err := newBase.AddAddress("OKEX", ExchangeAddress, currency.LTC, 0.03)
if err != nil {
@@ -428,6 +425,7 @@ func TestGetExchangePortfolio(t *testing.T) {
}
func TestGetPersonalPortfolio(t *testing.T) {
t.Parallel()
newBase := Base{}
err := newBase.AddAddress("someaddress", PersonalAddress, currency.N2O, 0.02)
if err != nil {
@@ -454,6 +452,7 @@ func TestGetPersonalPortfolio(t *testing.T) {
}
func TestGetPortfolioSummary(t *testing.T) {
t.Parallel()
newBase := Base{}
// Personal holdings
err := newBase.AddAddress("someaddress", PersonalAddress, currency.LTC, 1)
@@ -513,6 +512,7 @@ func TestGetPortfolioSummary(t *testing.T) {
}
func TestGetPortfolioGroupedCoin(t *testing.T) {
t.Parallel()
newBase := Base{}
err := newBase.AddAddress("someaddress", currency.LTC.String(), currency.LTC, 0.02)
if err != nil {
@@ -530,6 +530,7 @@ func TestGetPortfolioGroupedCoin(t *testing.T) {
}
func TestSeed(t *testing.T) {
t.Parallel()
newBase := Base{}
err := newBase.AddAddress("someaddress", currency.LTC.String(), currency.LTC, 0.02)
if err != nil {
@@ -541,6 +542,7 @@ func TestSeed(t *testing.T) {
}
func TestIsExchangeSupported(t *testing.T) {
t.Parallel()
newBase := seedPortFolioForTest(t)
ret := newBase.IsExchangeSupported("BTC Markets", core.BitcoinDonationAddress)
if !ret {
@@ -553,6 +555,7 @@ func TestIsExchangeSupported(t *testing.T) {
}
func TestIsColdStorage(t *testing.T) {
t.Parallel()
newBase := seedPortFolioForTest(t)
ret := newBase.IsColdStorage(core.BitcoinDonationAddress)
if !ret {
@@ -569,6 +572,7 @@ func TestIsColdStorage(t *testing.T) {
}
func TestIsWhiteListed(t *testing.T) {
t.Parallel()
b := seedPortFolioForTest(t)
ret := b.IsWhiteListed(core.BitcoinDonationAddress)
if !ret {
@@ -585,6 +589,7 @@ func TestIsWhiteListed(t *testing.T) {
}
func TestStartPortfolioWatcher(t *testing.T) {
t.Parallel()
newBase := Base{}
err := newBase.AddAddress("LX2LMYXtuv5tiYEMztSSoEZcafFPYJFRK1",
currency.LTC.String(),

View File

@@ -128,24 +128,22 @@ func TestMain(m *testing.M) {
os.Exit(0)
}
p.Addresses[1].SupportedExchanges = "BTC Markets,Binance"
banking.Accounts = append(banking.Accounts,
banking.Account{
Enabled: true,
ID: "test-bank-01",
BankName: "Test Bank",
BankAddress: "42 Bank Street",
BankPostalCode: "13337",
BankPostalCity: "Satoshiville",
BankCountry: "Japan",
AccountName: "Satoshi Nakamoto",
AccountNumber: "0234",
BSBNumber: "123456",
SWIFTCode: "91272837",
IBAN: "98218738671897",
SupportedCurrencies: "AUD,USD",
SupportedExchanges: "test-exchange",
},
banking.AppendAccounts(banking.Account{
Enabled: true,
ID: "test-bank-01",
BankName: "Test Bank",
BankAddress: "42 Bank Street",
BankPostalCode: "13337",
BankPostalCity: "Satoshiville",
BankCountry: "Japan",
AccountName: "Satoshi Nakamoto",
AccountNumber: "0234",
BSBNumber: "123456",
SWIFTCode: "91272837",
IBAN: "98218738671897",
SupportedCurrencies: "AUD,USD",
SupportedExchanges: "test-exchange",
},
)
os.Exit(m.Run())