--- tags: SET, non-functional --- # Non-functional tests ## Prerequisit - `M2` - recover tool which can be downloaded [here](https://drive.google.com/drive/folders/1z2GAi2rQ1wtj-iPP5wxQuQWJQGPEl9sy?usp=sharing) ## Recover from OMS files 0. To recover the service ungently we need `config.yaml` to be prepared which you can check example below ```yaml=== # As base DB db: postgres://postgres:postgres@localhost:5432/ mqurl: amqp://guest:guest@localhost:5672 exchange: me symbols: - symbol: zeus-usd db: zeus - symbol: zeus-usd2 # to override the whole db: postgres://postgres:postgres@localhost:5433/ # to override mqurl mqurl: amqp://guest:guest@localhost:5673 # to override exchange mqurl: tdx2 ``` 2. Increase ME commit interval to 600000 (10 minutes) 3. Spam orders 4. Stop rabbit mq 5. To recover database and oms data we have to collect required data from 4.1 OMS and then store to a separated directory e.g. `oms_logs` 4.2 ME log to a separated directory by run command below ```bash=== mkdir me_logs docker logs <me_container> > me_logs/me1.log docker logs <me_container> > me_logs/me2.log ``` 6. Bring RabbitMQ back so messages to OMSes should be resend after recovering 7. Then run recover ```bash=== ./m2 recovers --omsFileDir=./oms_logs --fileDir=./me_logs --configFile=config.yaml ``` Result ```bash=== Processing: db postgres://postgres:****@localhost:5432/zeus, symbol: zeus-usd Fetch state: 100.199ms lastOpID: 501, expected nextOpID: 502, startEventMsgId: 1631 Process: 107.255ms Pair: zeus-usd ┌─────────┬──────────┬────────┬───────────┬──────────┬───────┬────────┐ │ (index) │ table │ before │ inserteds │ updateds │ total │ lastId │ ├─────────┼──────────┼────────┼───────────┼──────────┼───────┼────────┤ │ 0 │ 'ops' │ 501 │ 1512 │ 0 │ 2013 │ 2013 │ │ 1 │ 'trades' │ 374 │ 1200 │ 0 │ 1574 │ 1574 │ │ 2 │ 'orders' │ 500 │ 1509 │ 105 │ 2009 │ 2009 │ └─────────┴──────────┴────────┴───────────┴──────────┴───────┴────────┘ Do you want to commit? (Y/n) new events: 5510 Feed events: 553.741ms Pair: zeus-usd ┌─────────┬──────────┬────────┬───────────┬──────────┬───────┬────────┐ │ (index) │ table │ before │ inserteds │ updateds │ total │ lastId │ ├─────────┼──────────┼────────┼───────────┼──────────┼───────┼────────┤ │ 0 │ 'ops' │ 501 │ 1512 │ 0 │ 2013 │ 2013 │ │ 1 │ 'trades' │ 374 │ 1200 │ 0 │ 1574 │ 1574 │ │ 2 │ 'orders' │ 500 │ 1509 │ 105 │ 2009 │ 2009 │ └─────────┴──────────┴────────┴───────────┴──────────┴───────┴────────┘ Committed: 4.748ms Save to db: 7.351s ========================================================================================== Processed all config ``` 8. All ME and oms data are recovered ## Recover in special cases 0. To recover the service ungently we need `config.yaml` to be prepared which you can check example below ```yaml=== db: postgres://postgres:postgres@localhost:5432/ mqurl: amqp://guest:guest@localhost:5672 exchange: me symbols: - symbol: zeus-usd db: zeus - symbol: zeus-usd2 # to override the whole db: postgres://postgres:postgres@localhost:5433/ # to override mqurl mqurl: amqp://guest:guest@localhost:5673 # to override exchange mqurl: tdx2 ``` 1. Prepare configs and queue so we can simulate and verify 1.1 Increase ME's commit interval to 600s so we can turn it down before commiting 1.2 Create queue name `all_op_results` and bind with routing keys `op_result.#` ### Push pull violation 2. Fire order like below the last order would not pass and be rejected by push pull reason and also save two data to verify 2.1 ME order book `:3030/orderbook` to save to json file 2.2 OMS events from this step to verify resents ```json=== # Create some orders and matched { "symbol": "zeus-usd", "price": "15", "qty": "1000", "op": "create", "side": "sell", "broker_id": "b1", "ref_id": "ref-1", "type": "limit", "account_id": "a1" } { "symbol": "zeus-usd", "price": "14", "qty": "500", "op": "create", "side": "buy", "broker_id": "b1", "ref_id": "ref-2", "type": "limit", "account_id": "a2" } { "symbol": "zeus-usd", "price": "16", "qty": "1000", "op": "create", "side": "buy", "broker_id": "b1", "ref_id": "ref-3", "type": "limit", "account_id": "a2" } # Cancel an open order { "order_id": 2, "symbol": "zeus-usd", "op": "cancel", "broker_id": "b1", "ref_id": "ref-4", "by": "system", "account_id": "a1" } # Then an order with same price and amount so this should be rejected { "symbol": "zeus-usd", "price": "14", "qty": "400", "op": "create", "side": "buy", "broker_id": "b1", "ref_id": "ref-1000005", "type": "limit", "account_id": "a2" } ``` 3. Turn off ME before commiting 4. Then pull messages from rabbit mq via command * NOTE: we need no data from oms since rabbit MQ still derivering messages ```bash=== mkdir mq_logs ./m2 pullevents --url=amqp://user:passwrd@mqurl:5672 --queue=all_op_results --timeout=30 > mq_logs/events.log ``` 5. Then recover ```bash=== ./m2 recovers --fileDir=./mq_logs --configFile=config.yaml ``` Result ```bash=== Processing: db postgres://postgres:****@localhost:5432/zeus, symbol: zeus-usd Fetch state: 80.201ms lastOpID: -1, expected nextOpID: 0, startEventMsgId: 1 Process: 1.067ms Pair: zeus-usd ┌─────────┬──────────┬────────┬───────────┬──────────┬───────┬────────┐ │ (index) │ table │ before │ inserteds │ updateds │ total │ lastId │ ├─────────┼──────────┼────────┼───────────┼──────────┼───────┼────────┤ │ 0 │ 'ops' │ 0 │ 5 │ 0 │ 5 │ 6 │ │ 1 │ 'trades' │ 0 │ 1 │ 0 │ 1 │ 1 │ │ 2 │ 'orders' │ 0 │ 4 │ 0 │ 4 │ 4 │ └─────────┴──────────┴────────┴───────────┴──────────┴───────┴────────┘ Do you want to commit? (Y/n) new events: 8 Feed events: 24.347ms Pair: zeus-usd ┌─────────┬──────────┬────────┬───────────┬──────────┬───────┬────────┐ │ (index) │ table │ before │ inserteds │ updateds │ total │ lastId │ ├─────────┼──────────┼────────┼───────────┼──────────┼───────┼────────┤ │ 0 │ 'ops' │ 0 │ 5 │ 0 │ 5 │ 6 │ │ 1 │ 'trades' │ 0 │ 1 │ 0 │ 1 │ 1 │ │ 2 │ 'orders' │ 0 │ 4 │ 0 │ 4 │ 4 │ └─────────┴──────────┴────────┴───────────┴──────────┴───────┴────────┘ Committed: 2.446ms Save to db: 34.511ms ========================================================================================== Processed all config ``` 6. Then start ME and verify 6.1 Order book via `:3030/orderbook` before and after recovering are identical(except timestamp) 6.2 Republished messages are equal to messages that be backuped at the first step ### frequent same price taker orders violation 7. Follow 2 - 6 with the order like below ```bash=== { "op": "create", "id": "0", "symbol": "zeus-usd", "type": "limit", "side": "buy", "price": "16", "qty": "1000", "value": "0", "broker_id": "b0", "account_id": "a0", "ref_id": "ref-0-limit-buy-open" } { "op": "create", "id": "0", "symbol": "zeus-usd", "type": "limit", "side": "sell", "price": "15", "qty": "1", "value": "0", "broker_id": "b1", "account_id": "a1", "ref_id": "ref-limit-sell-same-price-qty-ba-1" } { "op": "create", "id": "0", "symbol": "zeus-usd", "type": "limit", "side": "sell", "price": "15", "qty": "1", "value": "0", "broker_id": "b1", "account_id": "a1", "ref_id": "ref-limit-sell-same-price-qty-ba-2", "by": null, "inserted_at": "2022-01-06T10:37:11.219550520+07:00", "delay": 3 } { "op": "create", "id": "0", "symbol": "zeus-usd", "type": "limit", "side": "sell", "price": "15", "qty": "1", "value": "0", "broker_id": "b1", "account_id": "a1", "ref_id": "ref-limit-sell-same-price-qty-ba-3", "by": null, "inserted_at": "2022-01-06T10:37:11.219565128+07:00" } { "op": "create", "id": "0", "symbol": "zeus-usd", "type": "limit", "side": "sell", "price": "15", "qty": "1", "value": "0", "broker_id": "b1", "account_id": "a1", "ref_id": "ref-limit-sell-same-price-qty-ba-4", "by": null, "inserted_at": "2022-01-06T10:37:11.219565128+07:00" } { "op": "create", "id": "0", "symbol": "zeus-usd", "type": "limit", "side": "sell", "price": "15", "qty": "1", "value": "0", "broker_id": "b1", "account_id": "a1", "ref_id": "ref-limit-sell-same-price-qty-ba-5", "by": null, "inserted_at": "2022-01-06T10:37:11.219565128+07:00" } { "op": "create", "id": "0", "symbol": "zeus-usd", "type": "limit", "side": "sell", "price": "15", "qty": "1", "value": "0", "broker_id": "b1", "account_id": "a1", "ref_id": "ref-limit-sell-same-price-qty-ba-4->reject", "by": null, "inserted_at": "2022-01-06T10:37:11.219579675+07:00", "note": "should reject" } { "op": "create", "id": "0", "symbol": "zeus-usd", "type": "limit", "side": "sell", "price": "15", "qty": "1", "value": "0", "broker_id": "b1", "account_id": "a100", "ref_id": "ref-limit-sell-same-price-qty-not-ba-4->not-reject", "by": null, "inserted_at": "2022-01-06T10:37:11.219594123+07:00", "note": "should pass because different brokerage account" } ``` ### Price band 7. Check order via `:3030/orderbook` and `:3030/settings` and then try to generate orders that violate price band by lower ops ```bash=== { "op": "create", "id": "0", "symbol": "zeus-usd", "type": "limit", "side": "buy", "price": "10", "qty": "100", "value": "0", "broker_id": "b9", "account_id": "a9", "ref_id": "ref-0-pre-for-partial-reject" } { "op": "create", "id": "0", "symbol": "zeus-usd", "type": "limit", "side": "sell", "price": "10", "qty": "2000", "value": "0", "broker_id": "b10", "account_id": "a10", "ref_id": "ref-0-this-should-be-reject" } ``` 8. Repeat 3 - 6 to simulate and check results