mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-19 07:26:49 +00:00
* 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
949 lines
26 KiB
Go
949 lines
26 KiB
Go
package engine
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"strings"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gofrs/uuid"
|
|
"github.com/thrasher-corp/gocryptotrader/common"
|
|
"github.com/thrasher-corp/gocryptotrader/common/convert"
|
|
"github.com/thrasher-corp/gocryptotrader/config"
|
|
"github.com/thrasher-corp/gocryptotrader/currency"
|
|
"github.com/thrasher-corp/gocryptotrader/database"
|
|
"github.com/thrasher-corp/gocryptotrader/database/repository/datahistoryjob"
|
|
"github.com/thrasher-corp/gocryptotrader/database/repository/datahistoryjobresult"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
|
)
|
|
|
|
func TestSetupDataHistoryManager(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := SetupDataHistoryManager(nil, nil, nil)
|
|
if !errors.Is(err, errNilExchangeManager) {
|
|
t.Errorf("error '%v', expected '%v'", err, errNilConfig)
|
|
}
|
|
|
|
_, err = SetupDataHistoryManager(SetupExchangeManager(), nil, nil)
|
|
if !errors.Is(err, errNilDatabaseConnectionManager) {
|
|
t.Errorf("error '%v', expected '%v'", err, errNilDatabaseConnectionManager)
|
|
}
|
|
|
|
_, err = SetupDataHistoryManager(SetupExchangeManager(), &DatabaseConnectionManager{}, nil)
|
|
if !errors.Is(err, errNilConfig) {
|
|
t.Errorf("error '%v', expected '%v'", err, errNilConfig)
|
|
}
|
|
|
|
_, err = SetupDataHistoryManager(SetupExchangeManager(), &DatabaseConnectionManager{}, &config.DataHistoryManager{})
|
|
if !errors.Is(err, database.ErrNilInstance) {
|
|
t.Errorf("error '%v', expected '%v'", err, database.ErrNilInstance)
|
|
}
|
|
|
|
dbInst := &database.Instance{}
|
|
err = dbInst.SetConfig(&database.Config{Enabled: true})
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
dbInst.SetConnected(true)
|
|
dbCM := &DatabaseConnectionManager{
|
|
dbConn: dbInst,
|
|
started: 1,
|
|
}
|
|
err = dbInst.SetSQLiteConnection(&sql.DB{})
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
m, err := SetupDataHistoryManager(SetupExchangeManager(), dbCM, &config.DataHistoryManager{})
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if m == nil {
|
|
t.Fatal("expected manager")
|
|
}
|
|
}
|
|
|
|
func TestDataHistoryManagerIsRunning(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
m.started = 0
|
|
if m.IsRunning() {
|
|
t.Error("expected false")
|
|
}
|
|
m.started = 1
|
|
if !m.IsRunning() {
|
|
t.Error("expected true")
|
|
}
|
|
m = nil
|
|
if m.IsRunning() {
|
|
t.Error("expected false")
|
|
}
|
|
}
|
|
|
|
func TestDataHistoryManagerStart(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
m.started = 0
|
|
err := m.Start()
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
err = m.Start()
|
|
if !errors.Is(err, ErrSubSystemAlreadyStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemAlreadyStarted)
|
|
}
|
|
m = nil
|
|
err = m.Start()
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestDataHistoryManagerStop(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
m.shutdown = make(chan struct{})
|
|
err := m.Stop()
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
err = m.Stop()
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
m = nil
|
|
err = m.Stop()
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestUpsertJob(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
err := m.UpsertJob(nil, false)
|
|
if !errors.Is(err, errNilJob) {
|
|
t.Errorf("error '%v', expected '%v'", err, errNilJob)
|
|
}
|
|
dhj := &DataHistoryJob{}
|
|
err = m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, errNicknameUnset) {
|
|
t.Errorf("error '%v', expected '%v'", err, errNicknameUnset)
|
|
}
|
|
dhj.Nickname = "test1337"
|
|
err = m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Errorf("error '%v', expected '%v'", err, asset.ErrNotSupported)
|
|
}
|
|
|
|
dhj.Asset = asset.Spot
|
|
err = m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, errCurrencyPairUnset) {
|
|
t.Errorf("error '%v', expected '%v'", err, errCurrencyPairUnset)
|
|
}
|
|
|
|
dhj.Exchange = strings.ToLower(testExchange)
|
|
dhj.Pair = currency.NewPair(currency.BTC, currency.USDT)
|
|
err = m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, errCurrencyNotEnabled) {
|
|
t.Errorf("error '%v', expected '%v'", err, errCurrencyNotEnabled)
|
|
}
|
|
|
|
dhj.Pair = currency.NewPair(currency.BTC, currency.USD)
|
|
err = m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, kline.ErrUnsupportedInterval) {
|
|
t.Errorf("error '%v', expected '%v'", err, kline.ErrUnsupportedInterval)
|
|
}
|
|
|
|
dhj.Interval = kline.OneHour
|
|
err = m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, common.ErrDateUnset) {
|
|
t.Errorf("error '%v', expected '%v'", err, common.ErrDateUnset)
|
|
}
|
|
|
|
dhj.StartDate = time.Now().Add(-time.Hour)
|
|
dhj.EndDate = time.Now()
|
|
err = m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if len(m.jobs) != 1 {
|
|
t.Error("unexpected jerrb")
|
|
}
|
|
|
|
err = m.UpsertJob(dhj, true)
|
|
if !errors.Is(err, errNicknameInUse) {
|
|
t.Errorf("error '%v', expected '%v'", err, errNicknameInUse)
|
|
}
|
|
|
|
newJob := &DataHistoryJob{
|
|
Nickname: dhj.Nickname,
|
|
Exchange: testExchange,
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USD),
|
|
StartDate: startDate,
|
|
EndDate: time.Now().Add(-time.Minute),
|
|
Interval: kline.FifteenMin,
|
|
RunBatchLimit: 1338,
|
|
RequestSizeLimit: 1337,
|
|
DataType: 2,
|
|
MaxRetryAttempts: 1337,
|
|
}
|
|
err = m.UpsertJob(newJob, false)
|
|
if !errors.Is(err, errInvalidDataHistoryDataType) {
|
|
t.Errorf("error '%v', expected '%v'", err, errInvalidDataHistoryDataType)
|
|
}
|
|
|
|
newJob.DataType = dataHistoryTradeDataType
|
|
err = m.UpsertJob(newJob, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if !m.jobs[0].StartDate.Equal(startDate) {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestDeleteJob(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
dhj := &DataHistoryJob{
|
|
Nickname: "TestDeleteJob",
|
|
Exchange: testExchange,
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USD),
|
|
StartDate: time.Now().Add(-time.Minute * 5),
|
|
EndDate: time.Now(),
|
|
Interval: kline.OneMin,
|
|
}
|
|
err := m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
err = m.DeleteJob("", "")
|
|
if !errors.Is(err, errNicknameIDUnset) {
|
|
t.Errorf("error '%v', expected '%v'", err, errNicknameIDUnset)
|
|
}
|
|
|
|
err = m.DeleteJob("1337", "1337")
|
|
if !errors.Is(err, errOnlyNicknameOrID) {
|
|
t.Errorf("error '%v', expected '%v'", err, errOnlyNicknameOrID)
|
|
}
|
|
|
|
err = m.DeleteJob(dhj.Nickname, "")
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if len(m.jobs) != 0 {
|
|
t.Error("expected 0")
|
|
}
|
|
err = m.DeleteJob("", dhj.ID.String())
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
atomic.StoreInt32(&m.started, 0)
|
|
err = m.DeleteJob("", dhj.ID.String())
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
|
|
m = nil
|
|
err = m.DeleteJob("", dhj.ID.String())
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestGetByNickname(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
dhj := &DataHistoryJob{
|
|
Nickname: "TestGetByNickname",
|
|
Exchange: testExchange,
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USD),
|
|
StartDate: time.Now().Add(-time.Minute * 5),
|
|
EndDate: time.Now(),
|
|
Interval: kline.OneMin,
|
|
}
|
|
err := m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
_, err = m.GetByNickname(dhj.Nickname, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
_, err = m.GetByNickname(dhj.Nickname, true)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
m.jobs = []*DataHistoryJob{}
|
|
_, err = m.GetByNickname(dhj.Nickname, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
atomic.StoreInt32(&m.started, 0)
|
|
_, err = m.GetByNickname("test123", false)
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
|
|
m = nil
|
|
_, err = m.GetByNickname("test123", false)
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestGetByID(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
dhj := &DataHistoryJob{
|
|
Nickname: "TestGetByID",
|
|
Exchange: testExchange,
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USD),
|
|
StartDate: time.Now().Add(-time.Minute * 5),
|
|
EndDate: time.Now(),
|
|
Interval: kline.OneMin,
|
|
}
|
|
err := m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
_, err = m.GetByID(dhj.ID)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
_, err = m.GetByID(uuid.UUID{})
|
|
if !errors.Is(err, errEmptyID) {
|
|
t.Errorf("error '%v', expected '%v'", err, errEmptyID)
|
|
}
|
|
|
|
m.jobs = []*DataHistoryJob{}
|
|
_, err = m.GetByID(dhj.ID)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
atomic.StoreInt32(&m.started, 0)
|
|
_, err = m.GetByID(dhj.ID)
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
|
|
m = nil
|
|
_, err = m.GetByID(dhj.ID)
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestRetrieveJobs(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
dhj := &DataHistoryJob{
|
|
Nickname: "TestRetrieveJobs",
|
|
Exchange: testExchange,
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USD),
|
|
StartDate: time.Now().Add(-time.Minute * 5),
|
|
EndDate: time.Now(),
|
|
Interval: kline.OneMin,
|
|
}
|
|
err := m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
jobs, err := m.retrieveJobs()
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if len(jobs) != 1 {
|
|
t.Error("expected job")
|
|
}
|
|
|
|
atomic.StoreInt32(&m.started, 0)
|
|
_, err = m.retrieveJobs()
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
|
|
m = nil
|
|
_, err = m.retrieveJobs()
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestGetActiveJobs(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
|
|
jobs, err := m.GetActiveJobs()
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if len(jobs) != 0 {
|
|
t.Error("expected 0 jobs")
|
|
}
|
|
|
|
dhj := &DataHistoryJob{
|
|
Nickname: "TestGetActiveJobs",
|
|
Exchange: testExchange,
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USD),
|
|
StartDate: time.Now().Add(-time.Minute * 5),
|
|
EndDate: time.Now(),
|
|
Interval: kline.OneMin,
|
|
}
|
|
err = m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
jobs, err = m.GetActiveJobs()
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if len(jobs) != 1 {
|
|
t.Error("expected 1 job")
|
|
}
|
|
|
|
dhj.Status = dataHistoryStatusFailed
|
|
jobs, err = m.GetActiveJobs()
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if len(jobs) != 0 {
|
|
t.Error("expected 0 jobs")
|
|
}
|
|
|
|
atomic.StoreInt32(&m.started, 0)
|
|
_, err = m.GetActiveJobs()
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
|
|
m = nil
|
|
_, err = m.GetActiveJobs()
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestValidateJob(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
err := m.validateJob(nil)
|
|
if !errors.Is(err, errNilJob) {
|
|
t.Errorf("error '%v', expected '%v'", err, errNilJob)
|
|
}
|
|
dhj := &DataHistoryJob{}
|
|
err = m.validateJob(dhj)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Errorf("error '%v', expected '%v'", err, asset.ErrNotSupported)
|
|
}
|
|
|
|
dhj.Asset = asset.Spot
|
|
err = m.validateJob(dhj)
|
|
if !errors.Is(err, errCurrencyPairUnset) {
|
|
t.Errorf("error '%v', expected '%v'", err, errCurrencyPairUnset)
|
|
}
|
|
|
|
dhj.Exchange = testExchange
|
|
dhj.Pair = currency.NewPair(currency.BTC, currency.USDT)
|
|
err = m.validateJob(dhj)
|
|
if !errors.Is(err, errCurrencyNotEnabled) {
|
|
t.Errorf("error '%v', expected '%v'", err, errCurrencyNotEnabled)
|
|
}
|
|
|
|
dhj.Pair = currency.NewPair(currency.BTC, currency.USD)
|
|
err = m.validateJob(dhj)
|
|
if !errors.Is(err, kline.ErrUnsupportedInterval) {
|
|
t.Errorf("error '%v', expected '%v'", err, kline.ErrUnsupportedInterval)
|
|
}
|
|
|
|
dhj.Interval = kline.OneMin
|
|
err = m.validateJob(dhj)
|
|
if !errors.Is(err, common.ErrDateUnset) {
|
|
t.Errorf("error '%v', expected '%v'", err, common.ErrDateUnset)
|
|
}
|
|
|
|
dhj.StartDate = time.Now().Add(time.Minute)
|
|
dhj.EndDate = time.Now().Add(time.Hour)
|
|
err = m.validateJob(dhj)
|
|
if !errors.Is(err, common.ErrStartAfterTimeNow) {
|
|
t.Errorf("error '%v', expected '%v'", err, errInvalidTimes)
|
|
}
|
|
|
|
dhj.StartDate = time.Now().Add(-time.Hour)
|
|
dhj.EndDate = time.Now().Add(-time.Minute)
|
|
err = m.validateJob(dhj)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
}
|
|
|
|
func TestGetAllJobStatusBetween(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
|
|
dhj := &DataHistoryJob{
|
|
Nickname: "TestGetActiveJobs",
|
|
Exchange: testExchange,
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USD),
|
|
StartDate: time.Now().Add(-time.Minute * 5),
|
|
EndDate: time.Now(),
|
|
Interval: kline.OneMin,
|
|
}
|
|
err := m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
jobs, err := m.GetAllJobStatusBetween(time.Now().Add(-time.Minute*5), time.Now().Add(time.Minute))
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if len(jobs) != 1 {
|
|
t.Error("expected 1 job")
|
|
}
|
|
|
|
_, err = m.GetAllJobStatusBetween(time.Now().Add(-time.Hour), time.Now().Add(-time.Minute*30))
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
m.started = 0
|
|
_, err = m.GetAllJobStatusBetween(time.Now().Add(-time.Hour), time.Now().Add(-time.Minute*30))
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
|
|
m = nil
|
|
_, err = m.GetAllJobStatusBetween(time.Now().Add(-time.Hour), time.Now().Add(-time.Minute*30))
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestPrepareJobs(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
jobs, err := m.PrepareJobs()
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if len(jobs) != 1 {
|
|
t.Errorf("expected 1 job, received %v", len(jobs))
|
|
}
|
|
m.started = 0
|
|
_, err = m.PrepareJobs()
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
m = nil
|
|
_, err = m.PrepareJobs()
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestCompareJobsToData(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
dhj := &DataHistoryJob{
|
|
Nickname: "TestGenerateJobSummary",
|
|
Exchange: testExchange,
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USD),
|
|
StartDate: time.Now().Add(-time.Minute * 5),
|
|
EndDate: time.Now(),
|
|
Interval: kline.OneMin,
|
|
}
|
|
err := m.compareJobsToData(dhj)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
dhj.DataType = dataHistoryTradeDataType
|
|
err = m.compareJobsToData(dhj)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
dhj.DataType = 1337
|
|
err = m.compareJobsToData(dhj)
|
|
if !errors.Is(err, errUnknownDataType) {
|
|
t.Errorf("error '%v', expected '%v'", err, errUnknownDataType)
|
|
}
|
|
m.started = 0
|
|
err = m.compareJobsToData(dhj)
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
m = nil
|
|
err = m.compareJobsToData(dhj)
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestRunJob(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
dhj := &DataHistoryJob{
|
|
Nickname: "TestProcessJobs",
|
|
Exchange: "Binance",
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USDT),
|
|
StartDate: time.Now().Add(-time.Hour * 2),
|
|
EndDate: time.Now(),
|
|
Interval: kline.OneHour,
|
|
}
|
|
err := m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
err = m.runJob(dhj)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
dhj.Pair = currency.NewPair(currency.DOGE, currency.USDT)
|
|
err = m.runJob(dhj)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
dhjt := &DataHistoryJob{
|
|
Nickname: "TestProcessJobs2",
|
|
Exchange: "Binance",
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USDT),
|
|
StartDate: time.Now().Add(-time.Hour * 5),
|
|
EndDate: time.Now(),
|
|
Interval: kline.OneHour,
|
|
DataType: dataHistoryTradeDataType,
|
|
}
|
|
err = m.UpsertJob(dhjt, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
err = m.compareJobsToData(dhjt)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
err = m.runJob(dhjt)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
atomic.StoreInt32(&m.started, 0)
|
|
err = m.runJob(dhjt)
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
|
|
m = nil
|
|
err = m.runJob(dhjt)
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestGenerateJobSummaryTest(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
dhj := &DataHistoryJob{
|
|
Nickname: "TestGenerateJobSummary",
|
|
Exchange: testExchange,
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USD),
|
|
StartDate: time.Now().Add(-time.Minute * 5),
|
|
EndDate: time.Now(),
|
|
Interval: kline.OneMin,
|
|
}
|
|
err := m.UpsertJob(dhj, false)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
summary, err := m.GenerateJobSummary("TestGenerateJobSummary")
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if len(summary.ResultRanges) == 0 {
|
|
t.Error("expected result ranges")
|
|
}
|
|
|
|
atomic.StoreInt32(&m.started, 0)
|
|
_, err = m.GenerateJobSummary("TestGenerateJobSummary")
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
|
|
m = nil
|
|
_, err = m.GenerateJobSummary("TestGenerateJobSummary")
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestRunJobs(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
err := m.runJobs()
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
atomic.StoreInt32(&m.started, 0)
|
|
err = m.runJobs()
|
|
if !errors.Is(err, ErrSubSystemNotStarted) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrSubSystemNotStarted)
|
|
}
|
|
|
|
m = nil
|
|
err = m.runJobs()
|
|
if !errors.Is(err, ErrNilSubsystem) {
|
|
t.Errorf("error '%v', expected '%v'", err, ErrNilSubsystem)
|
|
}
|
|
}
|
|
|
|
func TestConverters(t *testing.T) {
|
|
t.Parallel()
|
|
m := createDHM(t)
|
|
id, err := uuid.NewV4()
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
id2, err := uuid.NewV4()
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
|
|
dhj := &DataHistoryJob{
|
|
ID: id,
|
|
Nickname: "TestProcessJobs",
|
|
Exchange: testExchange,
|
|
Asset: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USDT),
|
|
StartDate: time.Now().Add(-time.Hour * 24),
|
|
EndDate: time.Now(),
|
|
Interval: kline.OneHour,
|
|
}
|
|
|
|
dbJob := m.convertJobToDBModel(dhj)
|
|
if dhj.ID.String() != dbJob.ID ||
|
|
dhj.Nickname != dbJob.Nickname ||
|
|
!dhj.StartDate.Equal(dbJob.StartDate) ||
|
|
int64(dhj.Interval.Duration()) != dbJob.Interval ||
|
|
dhj.Pair.Base.String() != dbJob.Base ||
|
|
dhj.Pair.Quote.String() != dbJob.Quote {
|
|
t.Error("expected matching job")
|
|
}
|
|
|
|
convertBack, err := m.convertDBModelToJob(dbJob)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if dhj.ID != convertBack.ID ||
|
|
dhj.Nickname != convertBack.Nickname ||
|
|
!dhj.StartDate.Equal(convertBack.StartDate) ||
|
|
dhj.Interval != convertBack.Interval ||
|
|
!dhj.Pair.Equal(convertBack.Pair) {
|
|
t.Error("expected matching job")
|
|
}
|
|
|
|
jr := DataHistoryJobResult{
|
|
ID: id,
|
|
JobID: id2,
|
|
IntervalStartDate: dhj.StartDate,
|
|
IntervalEndDate: dhj.EndDate,
|
|
Status: 0,
|
|
Result: "test123",
|
|
Date: time.Now(),
|
|
}
|
|
mapperino := make(map[time.Time][]DataHistoryJobResult)
|
|
mapperino[dhj.StartDate] = append(mapperino[dhj.StartDate], jr)
|
|
result := m.convertJobResultToDBResult(mapperino)
|
|
if jr.ID.String() != result[0].ID ||
|
|
jr.JobID.String() != result[0].JobID ||
|
|
jr.Result != result[0].Result ||
|
|
!jr.Date.Equal(result[0].Date) ||
|
|
!jr.IntervalStartDate.Equal(result[0].IntervalStartDate) ||
|
|
!jr.IntervalEndDate.Equal(result[0].IntervalEndDate) ||
|
|
jr.Status != dataHistoryStatus(result[0].Status) {
|
|
t.Error("expected matching job")
|
|
}
|
|
|
|
andBackAgain, err := m.convertDBResultToJobResult(result)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
if jr.ID != andBackAgain[dhj.StartDate][0].ID ||
|
|
jr.JobID != andBackAgain[dhj.StartDate][0].JobID ||
|
|
jr.Result != andBackAgain[dhj.StartDate][0].Result ||
|
|
!jr.Date.Equal(andBackAgain[dhj.StartDate][0].Date) ||
|
|
!jr.IntervalStartDate.Equal(andBackAgain[dhj.StartDate][0].IntervalStartDate) ||
|
|
!jr.IntervalEndDate.Equal(andBackAgain[dhj.StartDate][0].IntervalEndDate) ||
|
|
jr.Status != andBackAgain[dhj.StartDate][0].Status {
|
|
t.Error("expected matching job")
|
|
}
|
|
}
|
|
|
|
// test helper functions
|
|
func createDHM(t *testing.T) *DataHistoryManager {
|
|
em := SetupExchangeManager()
|
|
exch, err := em.NewExchangeByName(testExchange)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
cp := currency.NewPair(currency.BTC, currency.USD)
|
|
exch.SetDefaults()
|
|
b := exch.GetBase()
|
|
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
|
|
b.CurrencyPairs.Pairs[asset.Spot] = ¤cy.PairStore{
|
|
Available: currency.Pairs{cp},
|
|
Enabled: currency.Pairs{cp},
|
|
AssetEnabled: convert.BoolPtr(true)}
|
|
em.Add(exch)
|
|
|
|
exch2, err := em.NewExchangeByName("Binance")
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("error '%v', expected '%v'", err, nil)
|
|
}
|
|
cp2 := currency.NewPair(currency.BTC, currency.USDT)
|
|
exch2.SetDefaults()
|
|
b = exch2.GetBase()
|
|
b.CurrencyPairs.Pairs = make(map[asset.Item]*currency.PairStore)
|
|
b.CurrencyPairs.Pairs[asset.Spot] = ¤cy.PairStore{
|
|
Available: currency.Pairs{cp2},
|
|
Enabled: currency.Pairs{cp2},
|
|
AssetEnabled: convert.BoolPtr(true),
|
|
ConfigFormat: ¤cy.PairFormat{Uppercase: true}}
|
|
em.Add(exch2)
|
|
m := &DataHistoryManager{
|
|
jobDB: dataHistoryJobService{},
|
|
jobResultDB: dataHistoryJobResultService{},
|
|
started: 1,
|
|
exchangeManager: em,
|
|
tradeLoader: dataHistoryTradeLoader,
|
|
candleLoader: dataHistoryCandleLoader,
|
|
interval: time.NewTicker(time.Minute),
|
|
}
|
|
return m
|
|
}
|
|
|
|
// these structs and function implementations are used
|
|
// to override database implementations as we are not testing those
|
|
// results here. see tests in the database folder
|
|
type dataHistoryJobService struct {
|
|
datahistoryjob.IDBService
|
|
}
|
|
|
|
type dataHistoryJobResultService struct {
|
|
datahistoryjobresult.IDBService
|
|
}
|
|
|
|
var (
|
|
jobID = "00a434e2-8502-4d6b-865f-e4243fd8b5a7"
|
|
startDate = time.Date(2020, 1, 1, 0, 0, 0, 0, time.Local)
|
|
endDate = time.Date(2021, 1, 1, 0, 0, 0, 0, time.Local)
|
|
)
|
|
|
|
func (d dataHistoryJobService) Upsert(_ ...*datahistoryjob.DataHistoryJob) error {
|
|
return nil
|
|
}
|
|
|
|
func (d dataHistoryJobService) GetByNickName(nickname string) (*datahistoryjob.DataHistoryJob, error) {
|
|
jc := j
|
|
jc.Nickname = nickname
|
|
return &jc, nil
|
|
}
|
|
|
|
func (d dataHistoryJobService) GetJobsBetween(_, _ time.Time) ([]datahistoryjob.DataHistoryJob, error) {
|
|
jc := j
|
|
return []datahistoryjob.DataHistoryJob{jc}, nil
|
|
}
|
|
|
|
func (d dataHistoryJobService) GetByID(id string) (*datahistoryjob.DataHistoryJob, error) {
|
|
jc := j
|
|
jc.ID = id
|
|
return &jc, nil
|
|
}
|
|
|
|
func (d dataHistoryJobService) GetAllIncompleteJobsAndResults() ([]datahistoryjob.DataHistoryJob, error) {
|
|
jc := j
|
|
return []datahistoryjob.DataHistoryJob{jc}, nil
|
|
}
|
|
|
|
func (d dataHistoryJobService) GetJobAndAllResults(nickname string) (*datahistoryjob.DataHistoryJob, error) {
|
|
jc := j
|
|
jc.Nickname = nickname
|
|
return &jc, nil
|
|
}
|
|
|
|
func (d dataHistoryJobResultService) Upsert(_ ...*datahistoryjobresult.DataHistoryJobResult) error {
|
|
return nil
|
|
}
|
|
|
|
func (d dataHistoryJobResultService) GetByJobID(_ string) ([]datahistoryjobresult.DataHistoryJobResult, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (d dataHistoryJobResultService) GetJobResultsBetween(_ string, _, _ time.Time) ([]datahistoryjobresult.DataHistoryJobResult, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
var j = datahistoryjob.DataHistoryJob{
|
|
ID: jobID,
|
|
Nickname: "datahistoryjob",
|
|
ExchangeName: testExchange,
|
|
Asset: "spot",
|
|
Base: "btc",
|
|
Quote: "usd",
|
|
StartDate: startDate,
|
|
EndDate: endDate,
|
|
Interval: int64(kline.OneHour.Duration()),
|
|
RequestSizeLimit: 3,
|
|
MaxRetryAttempts: 3,
|
|
BatchSize: 3,
|
|
CreatedDate: endDate,
|
|
Status: 0,
|
|
Results: []*datahistoryjobresult.DataHistoryJobResult{
|
|
{
|
|
ID: jobID,
|
|
JobID: jobID,
|
|
},
|
|
},
|
|
}
|
|
|
|
func dataHistoryTradeLoader(_, _, _, _ string, irh *kline.IntervalRangeHolder) error {
|
|
for i := range irh.Ranges {
|
|
for j := range irh.Ranges[i].Intervals {
|
|
irh.Ranges[i].Intervals[j].HasData = true
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func dataHistoryCandleLoader(string, currency.Pair, asset.Item, kline.Interval, time.Time, time.Time) (kline.Item, error) {
|
|
return kline.Item{}, nil
|
|
}
|