From 640a7e6a8343b622487cc44ff0be09919a5e05ab Mon Sep 17 00:00:00 2001 From: Andrey Grehov Date: Tue, 30 Oct 2018 20:24:15 -0400 Subject: [PATCH] ProcessOrderbook: added a condition to check for existing orderbooks (#197) * ProcessOrderbook: added a condition to check for existing orderbooks * ProcessOrderbook: simplified the logic by removing useless code * Covered orderbook read/write stability with tests * Fixes race condition writing to a test array --- exchanges/orderbook/orderbook.go | 21 +++------ exchanges/orderbook/orderbook_test.go | 64 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/exchanges/orderbook/orderbook.go b/exchanges/orderbook/orderbook.go index b0ebd527..5f29a63d 100644 --- a/exchanges/orderbook/orderbook.go +++ b/exchanges/orderbook/orderbook.go @@ -166,11 +166,6 @@ func ProcessOrderbook(exchangeName string, p pair.CurrencyPair, orderbookNew Bas orderbookNew.CurrencyPair = p.Pair().String() orderbookNew.LastUpdated = time.Now() - if len(Orderbooks) == 0 { - CreateNewOrderbook(exchangeName, p, orderbookNew, orderbookType) - return - } - orderbook, err := GetOrderbookByExchange(exchangeName) if err != nil { CreateNewOrderbook(exchangeName, p, orderbookNew, orderbookType) @@ -178,16 +173,12 @@ func ProcessOrderbook(exchangeName string, p pair.CurrencyPair, orderbookNew Bas } if FirstCurrencyExists(exchangeName, p.FirstCurrency) { - if !SecondCurrencyExists(exchangeName, p) { - m.Lock() - a := orderbook.Orderbook[p.FirstCurrency] - b := make(map[string]Base) - b[orderbookType] = orderbookNew - a[p.SecondCurrency] = b - orderbook.Orderbook[p.FirstCurrency] = a - m.Unlock() - return - } + m.Lock() + a := make(map[string]Base) + a[orderbookType] = orderbookNew + orderbook.Orderbook[p.FirstCurrency][p.SecondCurrency] = a + m.Unlock() + return } m.Lock() diff --git a/exchanges/orderbook/orderbook_test.go b/exchanges/orderbook/orderbook_test.go index f40bc834..aa2a2e29 100644 --- a/exchanges/orderbook/orderbook_test.go +++ b/exchanges/orderbook/orderbook_test.go @@ -1,6 +1,9 @@ package orderbook import ( + "math/rand" + "strconv" + "sync" "testing" "time" @@ -263,4 +266,65 @@ func TestProcessOrderbook(t *testing.T) { if a != 200 && b != 84000 { t.Fatal("Test failed. TestProcessOrderbook CalculateTotalsBids incorrect values") } + + type quick struct { + Name string + P pair.CurrencyPair + Bids []Item + Asks []Item + } + + var testArray []quick + + _ = rand.NewSource(time.Now().Unix()) + + var wg sync.WaitGroup + var m sync.Mutex + + for i := 0; i < 500; i++ { + wg.Add(1) + go func() { + newName := "Exchange" + strconv.FormatInt(rand.Int63(), 10) + newPairs := pair.NewCurrencyPair("BTC"+strconv.FormatInt(rand.Int63(), 10), + "USD"+strconv.FormatInt(rand.Int63(), 10)) + + asks := []Item{{Price: rand.Float64(), Amount: rand.Float64()}} + bids := []Item{{Price: rand.Float64(), Amount: rand.Float64()}} + base := Base{ + Pair: newPairs, + CurrencyPair: newPairs.Pair().String(), + Asks: asks, + Bids: bids, + } + + ProcessOrderbook(newName, newPairs, base, Spot) + m.Lock() + testArray = append(testArray, quick{Name: newName, P: newPairs, Bids: bids, Asks: asks}) + m.Unlock() + wg.Done() + }() + } + wg.Wait() + + for _, test := range testArray { + wg.Add(1) + go func(test quick) { + result, err := GetOrderbook(test.Name, test.P, Spot) + if err != nil { + t.Fatal("Test failed. TestProcessOrderbook failed to retrieve new orderbook") + } + + if result.Asks[0] != test.Asks[0] { + t.Error("Test failed. TestProcessOrderbook failed bad values") + } + + if result.Bids[0] != test.Bids[0] { + t.Error("Test failed. TestProcessOrderbook failed bad values") + } + + wg.Done() + }(test) + } + + wg.Wait() }