Files
gocryptotrader/exchanges/request/request_test.go
Scott ccfcdf26aa Engine: Protocol Features, coverage, types, BTC markets websocket (#368)
* Attempts to update orderbook so it doesn't need to sort

* Reverts the ws ob stuff. Gets rid of sorting because it happens later. Adds some exchange features

* update existing feature lists. Expands list definition to match my emotions

* Adds bithumb bitmex and bitstamp. adds a couple more types

* Features for you, features for me, features for bittrex, btcmarkets, btse, coinbasepro, coinut, exmo, gateio and gemini

* Features for hitbtc, huobi, itbit, kraken, lakebtc, lbank, localbitcoins, okcoin, okex, poloniex, yobit, zb

* Who can forget good old alphapoint?

* Adds btcmarksets websocket :glitch_crab: fixes alphapoint features

* Adds extra data not in the documentation :/

* Replaces websocket features by using protocol features. However, it breaks it due to import cycles. I'm not sure what I'll do just yet

* Removes import cycle via duplicate structs.

* Increases coverage of config with `TestCheckCurrencyConfigValues`. Moves all currency pair package types into their own files or places it at the bottom of files if necessary

* Increase coverage in code.go

* One way of determining a test has failed, is when to it fails. Removed redundant explanation

* Increases code coverage of conversion

* Lint fixes

* Fixes orderbook tests

* Re-adds sorting because its important to still have the internal pre-processed orderbook to be representative of a real orderbook

* Secret lints that did not show up via Windows linting

* Adds protocol package to contain exchange features

* Fixes protocol implementation

* Fixes ws tests

* Addresses the following: Removes st-st-stutters in config types, changes GetAvailableForexProviders -> GetSupportedForexProviders, removes errors from tests where error is nil, removes orderbook setup when not necessary, removes import newlines, removes false bools from declaration, changes should of to should have

* imports and casing

* Fixes two more nil error checks
2019-10-22 10:56:20 +11:00

330 lines
8.3 KiB
Go

package request
import (
"net/http"
"net/url"
"testing"
"time"
)
func TestNewRateLimit(t *testing.T) {
r := NewRateLimit(time.Second*10, 5)
if r.Duration != time.Second*10 && r.Rate != 5 {
t.Fatal("unexpected values")
}
}
func TestSetRate(t *testing.T) {
r := NewRateLimit(time.Second*10, 5)
r.SetRate(40)
if r.GetRate() != 40 {
t.Fatal("unexpected values")
}
}
func TestSetDuration(t *testing.T) {
r := NewRateLimit(time.Second*10, 5)
r.SetDuration(time.Second)
if r.GetDuration() != time.Second {
t.Fatal("unexpected values")
}
}
func TestDecerementRequests(t *testing.T) {
r := New("bitfinex", NewRateLimit(time.Second*10, 5), NewRateLimit(time.Second*20, 100), new(http.Client))
r.AuthLimit.SetRequests(99)
r.DecrementRequests(true)
if r.AuthLimit.GetRequests() != 98 {
t.Fatal("unexpected values")
}
}
func TestStartCycle(t *testing.T) {
r := New("bitfinex", NewRateLimit(time.Second*10, 5), NewRateLimit(time.Second*20, 100), new(http.Client))
if r.AuthLimit.Duration != time.Second*10 && r.AuthLimit.Rate != 5 {
t.Fatal("unexpected values")
}
if r.UnauthLimit.Duration != time.Second*20 && r.UnauthLimit.Rate != 100 {
t.Fatal("unexpected values")
}
r.AuthLimit.SetRequests(1)
r.UnauthLimit.SetRequests(1)
r.StartCycle()
if r.Cycle.IsZero() || r.AuthLimit.GetRequests() != 0 || r.UnauthLimit.GetRequests() != 0 {
t.Fatal("unexpcted values")
}
}
func TestIsRateLimited(t *testing.T) {
r := New("bitfinex", NewRateLimit(time.Second*10, 5), NewRateLimit(time.Second*20, 100), new(http.Client))
r.StartCycle()
if r.AuthLimit.String() != "Rate limiter set to 5 requests per 10s" {
t.Fatal("unexcpted values")
}
if r.UnauthLimit.String() != "Rate limiter set to 100 requests per 20s" {
t.Fatal("unexpected values")
}
if r.AuthLimit.String() != "Rate limiter set to 5 requests per 10s" {
t.Fatal("unexcpted values")
}
// FIXME: Need to account for unauth/auth/total requests
r.AuthLimit.SetRequests(4)
if r.AuthLimit.GetRequests() != 4 {
t.Fatal("unexpected values")
}
// test that we're not rate limited since 4 < 5
if r.IsRateLimited(true) {
t.Fatal("unexpected values")
}
// bump requests counter to 6 which would exceed the rate limiter
r.AuthLimit.SetRequests(6)
if !r.IsRateLimited(true) {
t.Fatal("unexpected values")
}
// FIXME: Need to account for unauth/auth/total requests
r.UnauthLimit.SetRequests(99)
if r.UnauthLimit.GetRequests() != 99 {
t.Fatal("unexpected values")
}
// test that we're not rate limited since 99 < 100
if r.IsRateLimited(false) {
t.Fatal("unexpected values")
}
// bump requests counter to 100 which would exceed the rate limiter
r.UnauthLimit.SetRequests(100)
if !r.IsRateLimited(false) {
t.Fatal("unexpected values")
}
}
func TestRequiresRateLimiter(t *testing.T) {
r := New("bitfinex", NewRateLimit(time.Second*10, 5), NewRateLimit(time.Second*20, 100), new(http.Client))
if !r.RequiresRateLimiter() {
t.Fatal("unexpected values")
}
r.AuthLimit.Rate = 0
r.UnauthLimit.Rate = 0
if r.RequiresRateLimiter() {
t.Fatal("unexpected values")
}
}
func TestSetLimit(t *testing.T) {
r := New("bitfinex", NewRateLimit(time.Second*10, 5), NewRateLimit(time.Second*20, 100), new(http.Client))
r.SetRateLimit(true, time.Minute, 20)
if r.AuthLimit.Rate != 20 && r.AuthLimit.Duration != time.Minute*20 {
t.Fatal("unexpected values")
}
r.SetRateLimit(false, time.Minute, 40)
if r.UnauthLimit.Rate != 40 && r.UnauthLimit.Duration != time.Minute {
t.Fatal("unexpected values")
}
}
func TestGetLimit(t *testing.T) {
r := New("bitfinex", NewRateLimit(time.Second*10, 5), NewRateLimit(time.Second*20, 100), new(http.Client))
if r.GetRateLimit(true).Duration != time.Second*10 && r.GetRateLimit(true).Rate != 5 {
t.Fatal("unexpected values")
}
if r.GetRateLimit(false).Duration != time.Second*10 && r.GetRateLimit(false).Rate != 100 {
t.Fatal("unexpected values")
}
}
func TestIsValidMethod(t *testing.T) {
for x := range supportedMethods {
if !IsValidMethod(supportedMethods[x]) {
t.Fatal("unexpected values")
}
}
if IsValidMethod("BLAH") {
t.Fatal("unexpected values")
}
}
func TestIsValidCycle(t *testing.T) {
r := New("bitfinex", NewRateLimit(time.Second*10, 5), NewRateLimit(time.Second*20, 100), new(http.Client))
r.Cycle = time.Now().Add(-9 * time.Second)
if !r.IsValidCycle(true) {
t.Fatal("unexpected values")
}
r.Cycle = time.Now().Add(-11 * time.Second)
if r.IsValidCycle(true) {
t.Fatal("unexpected values")
}
r.Cycle = time.Now().Add(-19 * time.Second)
if !r.IsValidCycle(false) {
t.Fatal("unexpected values")
}
r.Cycle = time.Now().Add(-21 * time.Second)
if r.IsValidCycle(false) {
t.Fatal("unexpected values")
}
}
func TestCheckRequest(t *testing.T) {
r := New("", NewRateLimit(time.Second*10, 5), NewRateLimit(time.Second*20, 100), new(http.Client))
_, err := r.checkRequest("bad method, bad", "http://www.google.com", nil, nil)
if err == nil {
t.Fatal("unexpected values")
}
}
func TestDoRequest(t *testing.T) {
var test = new(Requester)
err := test.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false, false)
if err == nil {
t.Fatal("Expected error")
}
r := New("", NewRateLimit(time.Second*10, 5), NewRateLimit(time.Second*20, 100), new(http.Client))
r.Name = "bitfinex"
err = r.SendPayload("BLAH", "https://www.google.com", nil, nil, nil, false, false, true, false, false)
if err == nil {
t.Fatal("Expected error")
}
err = r.SendPayload(http.MethodGet, "", nil, nil, nil, false, false, true, false, false)
if err == nil {
t.Fatal("Expected error")
}
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false, false)
if err != nil {
t.Fatal("unexpected values", err)
}
if !r.RequiresRateLimiter() {
t.Fatal("unexpected values")
}
r.SetRateLimit(false, time.Second, 0)
r.SetRateLimit(true, time.Second, 0)
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false, false)
if err != nil {
t.Fatal("unexpected values", err)
}
if r.RequiresRateLimiter() {
t.Fatal("unexpected values")
}
r.SetRateLimit(false, time.Millisecond*200, 100)
r.SetRateLimit(true, time.Millisecond*100, 100)
r.Cycle = time.Now().Add(time.Millisecond * -201)
if r.IsValidCycle(false) {
t.Fatal("unexpected values")
}
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false, false)
if err != nil {
t.Fatal("unexpected values")
}
r.Cycle = time.Now().Add(time.Millisecond * -101)
if r.IsValidCycle(true) {
t.Fatal("unexepcted values")
}
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, true, false, true, false, false)
if err != nil {
t.Fatal("unexpected values")
}
var result interface{}
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, result, false, false, true, false, false)
if err != nil {
t.Fatal(err)
}
headers := make(map[string]string)
headers["content-type"] = "content/text"
err = r.SendPayload(http.MethodPost, "https://bitfinex.com", headers, nil, result, false, false, true, false, false)
if err != nil {
t.Fatal(err)
}
r.StartCycle()
r.UnauthLimit.SetRequests(100)
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, result, false, false, false, false, false)
if err != nil {
t.Fatal("unexpected values")
}
err = r.SetTimeoutRetryAttempts(1)
if err != nil {
t.Fatal("setting timeout retry attempts")
}
err = r.SetTimeoutRetryAttempts(-1)
if err == nil {
t.Fatal("setting timeout retry attempts with negative value")
}
r.HTTPClient.Timeout = 1 * time.Second
err = r.SendPayload(http.MethodPost, "https://httpstat.us/200?sleep=20000", nil, nil, nil, false, false, true, false, false)
if err == nil {
t.Fatal("Expected error")
}
proxy, err := url.Parse("")
if err != nil {
t.Error("failed to parse proxy address")
}
err = r.SetProxy(proxy)
if err == nil {
t.Error("Expected error")
}
proxy, err = url.Parse("https://192.0.0.1")
if err != nil {
t.Error("failed to parse proxy address")
}
err = r.SetProxy(proxy)
if err != nil {
t.Error("failed to set proxy")
}
}
func BenchmarkRequestLockMech(b *testing.B) {
var r = new(Requester)
var meep interface{}
for n := 0; n < b.N; n++ {
r.SendPayload(http.MethodGet, "127.0.0.1", nil, nil, &meep, false, false, false, false, false)
}
}