exchanges/qa: Add exchange wrapper testing suite (#1159)

* initial concept of a nice validation tester for exchanges

* adds some datahandler design

* expand testing

* more tests and fixes

* minor end of day fix for bithumb

* fixes implementation issues

* more test coverage and improvements, but not sure if i should continue

* fix more wrapper implementations

* adds error type, more fixes

* changes signature, fixes implementations

* fixes more wrapper implementations

* one more bit

* more cleanup

* WOW things work?

* lintle 1/1337

* mini bump

* fixes all linting

* neaten

* GetOrderInfo+ asset pair fixes+improvements

* adds new websocket test

* expand ws testing

* fix bug, expand tests, improve implementation

* code coverage of a lot of new codes

* fixes everything

* reverts accidental changes

* minor fixes from reviewing code

* removes Bitfinex cancelBatchOrder implementation

* fixes dumb baby typo for babies

* mini nit fixes

* so many nits to address

* addresses all the nits

* Titlecase

* switcheroo

* removes websocket testing for now

* fix appveyor, minor test fix

* fixes typo, re-kindles killed kode

* skip binance wrapper tests when running CI

* expired context, huobi okx fixes

* kodespull

* fix ordering

* time fix because why not

* fix exmo, others

* hopefully this fixes all of my life's problems

* last thing today

* huobi, more like hypotrophy

* golangci-lint, more like mypooroldknee-splint

* fix huobi times by removing them

* should fix okx currency issues

* blocks the application

* adds last little contingency for pairs

* addresses most nits and new problems

* lovely fixed before seeing why okx sucks

* fixes issues with okx websocket

* the classic receieieivaier

* lintle

* adds test and fixes existing tests

* expands error handling messages during setup

* fixes dumb okx bugs introduced

* quick fix for lint and exmo

* fixes nixes

* fix exmo deposit issue

* lint

* fixes issue with extra asset runs missing

* fix surprise race

* all the lint and merge fixes

* fixes surprise bugs in OKx

* fixes issues with times and chains

* fixing all the merge stuff

* merge fix

* rm logs and a panic potential

* lovely lint lament

* an easy demonstration of scenario, but not of initial purpose

* put it in the bin

* Revert "put it in the bin"

This reverts commit 15c6490f713233d43f10957367fcbf18e3818bdd.

* re-add after immediate error popup

* fix mini poor test design

* okx okay

* merge fixes

* fixes issues discovered in lovely test

* I FORGOT TO COMMIT THIS

* nit fixaroonaboo

* forgoetten test fix

* revert old okx asset intrument work

* fixes

* revert problems I didnt understand. update bybit

* fix merge bugs

* test cleanup

* further improvements

* reshuffle and lint

* rm redundant CI_TEST by rm the CI_TEST field that is redundant

* path fix

* move to its own section, dont run on 32 bit + appveyor

* lint

* fix lbank

* address nits

* let it rip

* fix failing test time range

* niteroo boogaloo

* mod tidy, use common.SimpleTimeFormat
This commit is contained in:
Scott
2023-07-03 11:09:43 +10:00
committed by GitHub
parent ef605a3c19
commit fcc5ad4551
210 changed files with 38548 additions and 6519 deletions

View File

@@ -15,6 +15,7 @@ import (
"github.com/thrasher-corp/gocryptotrader/common/crypto"
"github.com/thrasher-corp/gocryptotrader/currency"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
)
@@ -217,7 +218,7 @@ func (b *Bittrex) GetHistoricalCandles(ctx context.Context, marketName, candleIn
// Retrieve full year
start = fmt.Sprintf("%d", year)
default:
return resp, fmt.Errorf("invalid interval %v, not supported", candleInterval)
return resp, fmt.Errorf("%w %v", kline.ErrUnsupportedInterval, candleInterval)
}
return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, fmt.Sprintf(getHistoricalCandles, marketName, candleType, candleInterval, start), &resp, nil)
@@ -371,7 +372,7 @@ func (b *Bittrex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path str
HTTPRecording: b.HTTPRecording,
HeaderResponse: resultHeader,
}
return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil })
return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }, request.UnauthenticatedRequest)
}
// SendAuthHTTPRequest sends an authenticated request
@@ -429,7 +430,6 @@ func (b *Bittrex) SendAuthHTTPRequest(ctx context.Context, ep exchange.URL, meth
Headers: headers,
Body: body,
Result: result,
AuthRequest: true,
Verbose: b.Verbose,
HTTPDebugging: b.HTTPDebugging,
HTTPRecording: b.HTTPRecording,
@@ -437,7 +437,7 @@ func (b *Bittrex) SendAuthHTTPRequest(ctx context.Context, ep exchange.URL, meth
}, nil
}
return b.SendPayload(ctx, request.Unset, newRequest)
return b.SendPayload(ctx, request.Unset, newRequest, request.AuthenticatedRequest)
}
// GetFee returns an estimate of fee based on type of transaction

View File

@@ -461,7 +461,7 @@ func TestGetActiveOrders(t *testing.T) {
t.Fatal(err)
}
var getOrdersRequest = order.GetOrdersRequest{
var getOrdersRequest = order.MultiOrderRequest{
Type: order.AnyType,
Pairs: []currency.Pair{p},
AssetType: asset.Spot,
@@ -479,7 +479,7 @@ func TestGetActiveOrders(t *testing.T) {
}
func TestGetOrderHistory(t *testing.T) {
var getOrdersRequest = order.GetOrdersRequest{
var getOrdersRequest = order.MultiOrderRequest{
Type: order.AnyType,
AssetType: asset.Spot,
Side: order.AnySide,
@@ -722,7 +722,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) {
start := time.Unix(1546300800, 0)
end := time.Unix(1577836799, 0)
_, err = b.GetHistoricCandlesExtended(context.Background(), pair, asset.Spot, kline.OneDay, start, end)
if !errors.Is(err, common.ErrNotYetImplemented) {
if !errors.Is(err, common.ErrFunctionNotSupported) {
t.Fatal(err)
}
}

View File

@@ -144,7 +144,7 @@ func (b *Bittrex) WsSignalRHandshake(ctx context.Context, result interface{}) er
}
return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) {
return item, nil
})
}, request.UnauthenticatedRequest)
}
// WsAuth sends an authentication message to receive auth data

View File

@@ -197,6 +197,11 @@ func (b *Bittrex) Setup(exch *config.Exchange) error {
})
}
// GetServerTime returns the current exchange server time.
func (b *Bittrex) GetServerTime(_ context.Context, _ asset.Item) (time.Time, error) {
return time.Time{}, common.ErrFunctionNotSupported
}
// Start starts the Bittrex go routine
func (b *Bittrex) Start(ctx context.Context, wg *sync.WaitGroup) error {
if wg == nil {
@@ -256,7 +261,7 @@ func (b *Bittrex) Run(ctx context.Context) {
func (b *Bittrex) FetchTradablePairs(ctx context.Context, a asset.Item) (currency.Pairs, error) {
// Bittrex only supports spot trading
if !b.SupportsAsset(a) {
return nil, fmt.Errorf("asset type of %s is not supported by %s", a, b.Name)
return nil, fmt.Errorf("%w %v", asset.ErrNotSupported, a)
}
markets, err := b.GetMarkets(ctx)
if err != nil {
@@ -285,7 +290,11 @@ func (b *Bittrex) UpdateTradablePairs(ctx context.Context, forceUpdate bool) err
if err != nil {
return err
}
return b.UpdatePairs(pairs, asset.Spot, false, forceUpdate)
err = b.UpdatePairs(pairs, asset.Spot, false, forceUpdate)
if err != nil {
return err
}
return b.EnsureOnePairEnabled()
}
// UpdateTickers updates the ticker for all currency pairs of a given asset type
@@ -362,6 +371,12 @@ func (b *Bittrex) FetchOrderbook(ctx context.Context, c currency.Pair, assetType
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (b *Bittrex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) {
if p.IsEmpty() {
return nil, currency.ErrCurrencyPairEmpty
}
if err := b.CurrencyPairs.IsAssetEnabled(assetType); err != nil {
return nil, err
}
book := &orderbook.Base{
Exchange: b.Name,
Pair: p,
@@ -375,8 +390,7 @@ func (b *Bittrex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetTyp
}
// Valid order book depths are 1, 25 and 500
orderbookData, sequence, err := b.GetOrderbook(ctx,
formattedPair.String(), orderbookDepth)
orderbookData, sequence, err := b.GetOrderbook(ctx, formattedPair.String(), orderbookDepth)
if err != nil {
return book, err
}
@@ -450,9 +464,9 @@ func (b *Bittrex) FetchAccountInfo(ctx context.Context, assetType asset.Item) (a
return resp, nil
}
// GetFundingHistory returns funding history, deposits and
// GetAccountFundingHistory returns funding history, deposits and
// withdrawals
func (b *Bittrex) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) {
func (b *Bittrex) GetAccountFundingHistory(ctx context.Context) ([]exchange.FundingHistory, error) {
closedDepositData, err := b.GetClosedDeposits(ctx)
if err != nil {
return nil, err
@@ -478,9 +492,9 @@ func (b *Bittrex) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory
withdrawalData = append(withdrawalData, closedWithdrawalData...)
withdrawalData = append(withdrawalData, openWithdrawalData...)
resp := make([]exchange.FundHistory, 0, len(depositData)+len(withdrawalData))
resp := make([]exchange.FundingHistory, 0, len(depositData)+len(withdrawalData))
for x := range depositData {
resp = append(resp, exchange.FundHistory{
resp = append(resp, exchange.FundingHistory{
ExchangeName: b.Name,
Status: depositData[x].Status,
Description: depositData[x].CryptoAddressTag,
@@ -493,7 +507,7 @@ func (b *Bittrex) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory
})
}
for x := range withdrawalData {
resp = append(resp, exchange.FundHistory{
resp = append(resp, exchange.FundingHistory{
ExchangeName: b.Name,
Status: withdrawalData[x].Status,
Description: withdrawalData[x].CryptoAddressTag,
@@ -512,7 +526,7 @@ func (b *Bittrex) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory
// GetWithdrawalsHistory returns previous withdrawals data
func (b *Bittrex) GetWithdrawalsHistory(_ context.Context, _ currency.Code, _ asset.Item) (resp []exchange.WithdrawalHistory, err error) {
return nil, common.ErrNotYetImplemented
return nil, common.ErrFunctionNotSupported
}
// GetRecentTrades returns the most recent trades for a currency and asset
@@ -610,8 +624,8 @@ func (b *Bittrex) CancelOrder(ctx context.Context, ord *order.Cancel) error {
}
// CancelBatchOrders cancels an orders by their corresponding ID numbers
func (b *Bittrex) CancelBatchOrders(_ context.Context, _ []order.Cancel) (order.CancelBatchResponse, error) {
return order.CancelBatchResponse{}, common.ErrNotYetImplemented
func (b *Bittrex) CancelBatchOrders(_ context.Context, _ []order.Cancel) (*order.CancelBatchResponse, error) {
return nil, common.ErrFunctionNotSupported
}
// CancelAllOrders cancels all orders associated with a currency pair, or cancels all orders for all
@@ -644,17 +658,17 @@ func (b *Bittrex) CancelAllOrders(ctx context.Context, orderCancellation *order.
}
// GetOrderInfo returns information on a current open order
func (b *Bittrex) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (order.Detail, error) {
func (b *Bittrex) GetOrderInfo(ctx context.Context, orderID string, _ currency.Pair, _ asset.Item) (*order.Detail, error) {
orderData, err := b.GetOrder(ctx, orderID)
if err != nil {
return order.Detail{}, err
return nil, err
}
return b.ConstructOrderDetail(&orderData)
}
// ConstructOrderDetail constructs an order detail item from the underlying data
func (b *Bittrex) ConstructOrderDetail(orderData *OrderData) (order.Detail, error) {
func (b *Bittrex) ConstructOrderDetail(orderData *OrderData) (*order.Detail, error) {
immediateOrCancel := false
if orderData.TimeInForce == string(ImmediateOrCancel) {
immediateOrCancel = true
@@ -662,7 +676,7 @@ func (b *Bittrex) ConstructOrderDetail(orderData *OrderData) (order.Detail, erro
format, err := b.GetPairFormat(asset.Spot, false)
if err != nil {
return order.Detail{}, err
return nil, err
}
orderPair, err := currency.NewPairDelimiter(orderData.MarketSymbol,
format.Delimiter)
@@ -699,7 +713,7 @@ func (b *Bittrex) ConstructOrderDetail(orderData *OrderData) (order.Detail, erro
}
}
resp := order.Detail{
return &order.Detail{
ImmediateOrCancel: immediateOrCancel,
Amount: orderData.Quantity,
ExecutedAmount: orderData.FillQuantity,
@@ -711,8 +725,7 @@ func (b *Bittrex) ConstructOrderDetail(orderData *OrderData) (order.Detail, erro
Type: orderType,
Pair: orderPair,
Status: orderStatus,
}
return resp, nil
}, nil
}
// GetDepositAddress returns a deposit address for a specified currency
@@ -762,7 +775,7 @@ func (b *Bittrex) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *wit
}
// GetActiveOrders retrieves any orders that are active/open
func (b *Bittrex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
func (b *Bittrex) GetActiveOrders(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
@@ -834,7 +847,7 @@ func (b *Bittrex) GetActiveOrders(ctx context.Context, req *order.GetOrdersReque
// GetOrderHistory retrieves account order information
// Can Limit response to specific order status
func (b *Bittrex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (order.FilteredOrders, error) {
func (b *Bittrex) GetOrderHistory(ctx context.Context, req *order.MultiOrderRequest) (order.FilteredOrders, error) {
err := req.Validate()
if err != nil {
return nil, err
@@ -1045,5 +1058,6 @@ func (b *Bittrex) GetHistoricCandles(ctx context.Context, pair currency.Pair, a
// GetHistoricCandlesExtended returns candles between a time period for a set time interval
func (b *Bittrex) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _ kline.Interval, _, _ time.Time) (*kline.Item, error) {
return nil, common.ErrNotYetImplemented
// TODO implement with API upgrade˜
return nil, common.ErrFunctionNotSupported
}