aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2018-04-20 20:20:02 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2018-04-21 00:42:16 +0200
commit1593c7a9f58ffaea8933f30f683f67c2b155f6b2 (patch)
tree1191b8438f1f7d52aa7ef736ec2def0595e311d0 /tests
parentceb7fc4c9e76857fefbe1dfe3f4dd3830d065a6f (diff)
downloadTrader-1593c7a9f58ffaea8933f30f683f67c2b155f6b2.tar.gz
Trader-1593c7a9f58ffaea8933f30f683f67c2b155f6b2.tar.zst
Trader-1593c7a9f58ffaea8933f30f683f67c2b155f6b2.zip
Store some information to redis
Diffstat (limited to 'tests')
-rw-r--r--tests/test_main.py53
-rw-r--r--tests/test_market.py84
-rw-r--r--tests/test_store.py47
3 files changed, 169 insertions, 15 deletions
diff --git a/tests/test_main.py b/tests/test_main.py
index d2f8029..b650870 100644
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -135,16 +135,16 @@ class MainTest(WebMockTestCase):
135 args_mock.after = "after" 135 args_mock.after = "after"
136 self.assertEqual("", stdout_mock.getvalue()) 136 self.assertEqual("", stdout_mock.getvalue())
137 137
138 main.process("config", 3, 1, args_mock, "pg_config") 138 main.process("config", 3, 1, args_mock, "pg_config", "redis_config")
139 139
140 market_mock.from_config.assert_has_calls([ 140 market_mock.from_config.assert_has_calls([
141 mock.call("config", args_mock, pg_config="pg_config", market_id=3, user_id=1), 141 mock.call("config", args_mock, pg_config="pg_config", redis_config="redis_config", market_id=3, user_id=1),
142 mock.call().process("action", before="before", after="after"), 142 mock.call().process("action", before="before", after="after"),
143 ]) 143 ])
144 144
145 with self.subTest(exception=True): 145 with self.subTest(exception=True):
146 market_mock.from_config.side_effect = Exception("boo") 146 market_mock.from_config.side_effect = Exception("boo")
147 main.process(3, "config", 1, args_mock, "pg_config") 147 main.process(3, "config", 1, args_mock, "pg_config", "redis_config")
148 self.assertEqual("Exception: boo\n", stdout_mock.getvalue()) 148 self.assertEqual("Exception: boo\n", stdout_mock.getvalue())
149 149
150 def test_main(self): 150 def test_main(self):
@@ -159,7 +159,7 @@ class MainTest(WebMockTestCase):
159 args_mock.user = "user" 159 args_mock.user = "user"
160 parse_args.return_value = args_mock 160 parse_args.return_value = args_mock
161 161
162 parse_config.return_value = "pg_config" 162 parse_config.return_value = ["pg_config", "redis_config"]
163 163
164 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]] 164 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]]
165 165
@@ -171,8 +171,8 @@ class MainTest(WebMockTestCase):
171 171
172 self.assertEqual(2, process.call_count) 172 self.assertEqual(2, process.call_count)
173 process.assert_has_calls([ 173 process.assert_has_calls([
174 mock.call("config1", 3, 1, args_mock, "pg_config"), 174 mock.call("config1", 3, 1, args_mock, "pg_config", "redis_config"),
175 mock.call("config2", 1, 2, args_mock, "pg_config"), 175 mock.call("config2", 1, 2, args_mock, "pg_config", "redis_config"),
176 ]) 176 ])
177 with self.subTest(parallel=True): 177 with self.subTest(parallel=True):
178 with mock.patch("main.parse_args") as parse_args,\ 178 with mock.patch("main.parse_args") as parse_args,\
@@ -187,7 +187,7 @@ class MainTest(WebMockTestCase):
187 args_mock.user = "user" 187 args_mock.user = "user"
188 parse_args.return_value = args_mock 188 parse_args.return_value = args_mock
189 189
190 parse_config.return_value = "pg_config" 190 parse_config.return_value = ["pg_config", "redis_config"]
191 191
192 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]] 192 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]]
193 193
@@ -202,9 +202,9 @@ class MainTest(WebMockTestCase):
202 self.assertEqual(2, process.call_count) 202 self.assertEqual(2, process.call_count)
203 process.assert_has_calls([ 203 process.assert_has_calls([
204 mock.call.__bool__(), 204 mock.call.__bool__(),
205 mock.call("config1", 3, 1, args_mock, "pg_config"), 205 mock.call("config1", 3, 1, args_mock, "pg_config", "redis_config"),
206 mock.call.__bool__(), 206 mock.call.__bool__(),
207 mock.call("config2", 1, 2, args_mock, "pg_config"), 207 mock.call("config2", 1, 2, args_mock, "pg_config", "redis_config"),
208 ]) 208 ])
209 with self.subTest(quiet=True): 209 with self.subTest(quiet=True):
210 with mock.patch("main.parse_args") as parse_args,\ 210 with mock.patch("main.parse_args") as parse_args,\
@@ -219,7 +219,7 @@ class MainTest(WebMockTestCase):
219 args_mock.user = "user" 219 args_mock.user = "user"
220 parse_args.return_value = args_mock 220 parse_args.return_value = args_mock
221 221
222 parse_config.return_value = "pg_config" 222 parse_config.return_value = ["pg_config", "redis_config"]
223 223
224 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]] 224 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]]
225 225
@@ -240,7 +240,7 @@ class MainTest(WebMockTestCase):
240 args_mock.user = "user" 240 args_mock.user = "user"
241 parse_args.return_value = args_mock 241 parse_args.return_value = args_mock
242 242
243 parse_config.return_value = "pg_config" 243 parse_config.return_value = ["pg_config", "redis_config"]
244 244
245 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]] 245 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]]
246 246
@@ -259,15 +259,39 @@ class MainTest(WebMockTestCase):
259 "db_user": "user", 259 "db_user": "user",
260 "db_password": "password", 260 "db_password": "password",
261 "db_database": "database", 261 "db_database": "database",
262 "redis_host": "rhost",
263 "redis_port": "rport",
264 "redis_database": "rdb",
262 "report_path": None, 265 "report_path": None,
263 }) 266 })
264 267
265 result = main.parse_config(args) 268 db_config, redis_config = main.parse_config(args)
266 self.assertEqual({ "host": "host", "port": "port", "user": 269 self.assertEqual({ "host": "host", "port": "port", "user":
267 "user", "password": "password", "database": "database" 270 "user", "password": "password", "database": "database"
268 }, result) 271 }, db_config)
272 self.assertEqual({ "host": "rhost", "port": "rport", "db":
273 "rdb"}, redis_config)
274
269 with self.assertRaises(AttributeError): 275 with self.assertRaises(AttributeError):
270 args.db_password 276 args.db_password
277 with self.assertRaises(AttributeError):
278 args.redis_host
279
280 with self.subTest(redis_host="socket"):
281 args = main.configargparse.Namespace(**{
282 "db_host": "host",
283 "db_port": "port",
284 "db_user": "user",
285 "db_password": "password",
286 "db_database": "database",
287 "redis_host": "/run/foo",
288 "redis_port": "rport",
289 "redis_database": "rdb",
290 "report_path": None,
291 })
292
293 db_config, redis_config = main.parse_config(args)
294 self.assertEqual({ "unix_socket_path": "/run/foo", "db": "rdb"}, redis_config)
271 295
272 with self.subTest(report_path="present"): 296 with self.subTest(report_path="present"):
273 args = main.configargparse.Namespace(**{ 297 args = main.configargparse.Namespace(**{
@@ -276,6 +300,9 @@ class MainTest(WebMockTestCase):
276 "db_user": "user", 300 "db_user": "user",
277 "db_password": "password", 301 "db_password": "password",
278 "db_database": "database", 302 "db_database": "database",
303 "redis_host": "rhost",
304 "redis_port": "rport",
305 "redis_database": "rdb",
279 "report_path": "report_path", 306 "report_path": "report_path",
280 }) 307 })
281 308
diff --git a/tests/test_market.py b/tests/test_market.py
index b41cd6a..e3482b8 100644
--- a/tests/test_market.py
+++ b/tests/test_market.py
@@ -530,23 +530,55 @@ class MarketTest(WebMockTestCase):
530 m.store_database_report(datetime.datetime(2018, 3, 24)) 530 m.store_database_report(datetime.datetime(2018, 3, 24))
531 self.assertEqual(stdout_mock.getvalue(), "impossible to store report to database: Exception; Bouh\n") 531 self.assertEqual(stdout_mock.getvalue(), "impossible to store report to database: Exception; Bouh\n")
532 532
533 @mock.patch.object(market, "redis")
534 def test_store_redis_report(self, redis):
535 connect_mock = mock.Mock()
536 redis.Redis.return_value = connect_mock
537
538 m = market.Market(self.ccxt, self.market_args(),
539 redis_config={"config": "redis_config"}, market_id=1)
540
541 with self.subTest(error=False),\
542 mock.patch.object(m, "report") as report:
543 report.to_json_redis.return_value = [
544 ("type1", "payload1"),
545 ("type2", "payload2"),
546 ]
547 m.store_redis_report(datetime.datetime(2018, 3, 24))
548 connect_mock.assert_has_calls([
549 mock.call.set("/cryptoportfolio/1/2018-03-24T00:00:00/type1", "payload1", ex=31*24*60*60),
550 mock.call.set("/cryptoportfolio/1/latest/type1", "payload1"),
551 mock.call.set("/cryptoportfolio/1/2018-03-24T00:00:00/type2", "payload2", ex=31*24*60*60),
552 mock.call.set("/cryptoportfolio/1/latest/type2", "payload2"),
553 ])
554
555 connect_mock.reset_mock()
556 with self.subTest(error=True),\
557 mock.patch('sys.stdout', new_callable=StringIO) as stdout_mock:
558 redis.Redis.side_effect = Exception("Bouh")
559 m.store_redis_report(datetime.datetime(2018, 3, 24))
560 self.assertEqual(stdout_mock.getvalue(), "impossible to store report to redis: Exception; Bouh\n")
561
533 def test_store_report(self): 562 def test_store_report(self):
534 m = market.Market(self.ccxt, self.market_args(report_db=False), user_id=1) 563 m = market.Market(self.ccxt, self.market_args(report_db=False), user_id=1)
535 with self.subTest(file=None, pg_config=None),\ 564 with self.subTest(file=None, pg_config=None),\
536 mock.patch.object(m, "report") as report,\ 565 mock.patch.object(m, "report") as report,\
537 mock.patch.object(m, "store_database_report") as db_report,\ 566 mock.patch.object(m, "store_database_report") as db_report,\
567 mock.patch.object(m, "store_redis_report") as redis_report,\
538 mock.patch.object(m, "store_file_report") as file_report: 568 mock.patch.object(m, "store_file_report") as file_report:
539 m.store_report() 569 m.store_report()
540 report.merge.assert_called_with(store.Portfolio.report) 570 report.merge.assert_called_with(store.Portfolio.report)
541 571
542 file_report.assert_not_called() 572 file_report.assert_not_called()
543 db_report.assert_not_called() 573 db_report.assert_not_called()
574 redis_report.assert_not_called()
544 575
545 report.reset_mock() 576 report.reset_mock()
546 m = market.Market(self.ccxt, self.market_args(report_db=False, report_path="present"), user_id=1) 577 m = market.Market(self.ccxt, self.market_args(report_db=False, report_path="present"), user_id=1)
547 with self.subTest(file="present", pg_config=None),\ 578 with self.subTest(file="present", pg_config=None),\
548 mock.patch.object(m, "report") as report,\ 579 mock.patch.object(m, "report") as report,\
549 mock.patch.object(m, "store_file_report") as file_report,\ 580 mock.patch.object(m, "store_file_report") as file_report,\
581 mock.patch.object(m, "store_redis_report") as redis_report,\
550 mock.patch.object(m, "store_database_report") as db_report,\ 582 mock.patch.object(m, "store_database_report") as db_report,\
551 mock.patch.object(market.datetime, "datetime") as time_mock: 583 mock.patch.object(market.datetime, "datetime") as time_mock:
552 584
@@ -557,12 +589,14 @@ class MarketTest(WebMockTestCase):
557 report.merge.assert_called_with(store.Portfolio.report) 589 report.merge.assert_called_with(store.Portfolio.report)
558 file_report.assert_called_once_with(datetime.datetime(2018, 2, 25)) 590 file_report.assert_called_once_with(datetime.datetime(2018, 2, 25))
559 db_report.assert_not_called() 591 db_report.assert_not_called()
592 redis_report.assert_not_called()
560 593
561 report.reset_mock() 594 report.reset_mock()
562 m = market.Market(self.ccxt, self.market_args(report_db=True, report_path="present"), user_id=1) 595 m = market.Market(self.ccxt, self.market_args(report_db=True, report_path="present"), user_id=1)
563 with self.subTest(file="present", pg_config=None, report_db=True),\ 596 with self.subTest(file="present", pg_config=None, report_db=True),\
564 mock.patch.object(m, "report") as report,\ 597 mock.patch.object(m, "report") as report,\
565 mock.patch.object(m, "store_file_report") as file_report,\ 598 mock.patch.object(m, "store_file_report") as file_report,\
599 mock.patch.object(m, "store_redis_report") as redis_report,\
566 mock.patch.object(m, "store_database_report") as db_report,\ 600 mock.patch.object(m, "store_database_report") as db_report,\
567 mock.patch.object(market.datetime, "datetime") as time_mock: 601 mock.patch.object(market.datetime, "datetime") as time_mock:
568 602
@@ -573,12 +607,14 @@ class MarketTest(WebMockTestCase):
573 report.merge.assert_called_with(store.Portfolio.report) 607 report.merge.assert_called_with(store.Portfolio.report)
574 file_report.assert_called_once_with(datetime.datetime(2018, 2, 25)) 608 file_report.assert_called_once_with(datetime.datetime(2018, 2, 25))
575 db_report.assert_not_called() 609 db_report.assert_not_called()
610 redis_report.assert_not_called()
576 611
577 report.reset_mock() 612 report.reset_mock()
578 m = market.Market(self.ccxt, self.market_args(report_db=True), pg_config="present", user_id=1) 613 m = market.Market(self.ccxt, self.market_args(report_db=True), pg_config="present", user_id=1)
579 with self.subTest(file=None, pg_config="present"),\ 614 with self.subTest(file=None, pg_config="present"),\
580 mock.patch.object(m, "report") as report,\ 615 mock.patch.object(m, "report") as report,\
581 mock.patch.object(m, "store_file_report") as file_report,\ 616 mock.patch.object(m, "store_file_report") as file_report,\
617 mock.patch.object(m, "store_redis_report") as redis_report,\
582 mock.patch.object(m, "store_database_report") as db_report,\ 618 mock.patch.object(m, "store_database_report") as db_report,\
583 mock.patch.object(market.datetime, "datetime") as time_mock: 619 mock.patch.object(market.datetime, "datetime") as time_mock:
584 620
@@ -589,6 +625,7 @@ class MarketTest(WebMockTestCase):
589 report.merge.assert_called_with(store.Portfolio.report) 625 report.merge.assert_called_with(store.Portfolio.report)
590 file_report.assert_not_called() 626 file_report.assert_not_called()
591 db_report.assert_called_once_with(datetime.datetime(2018, 2, 25)) 627 db_report.assert_called_once_with(datetime.datetime(2018, 2, 25))
628 redis_report.assert_not_called()
592 629
593 report.reset_mock() 630 report.reset_mock()
594 m = market.Market(self.ccxt, self.market_args(report_db=True, report_path="present"), 631 m = market.Market(self.ccxt, self.market_args(report_db=True, report_path="present"),
@@ -596,6 +633,7 @@ class MarketTest(WebMockTestCase):
596 with self.subTest(file="present", pg_config="present"),\ 633 with self.subTest(file="present", pg_config="present"),\
597 mock.patch.object(m, "report") as report,\ 634 mock.patch.object(m, "report") as report,\
598 mock.patch.object(m, "store_file_report") as file_report,\ 635 mock.patch.object(m, "store_file_report") as file_report,\
636 mock.patch.object(m, "store_redis_report") as redis_report,\
599 mock.patch.object(m, "store_database_report") as db_report,\ 637 mock.patch.object(m, "store_database_report") as db_report,\
600 mock.patch.object(market.datetime, "datetime") as time_mock: 638 mock.patch.object(market.datetime, "datetime") as time_mock:
601 639
@@ -606,6 +644,52 @@ class MarketTest(WebMockTestCase):
606 report.merge.assert_called_with(store.Portfolio.report) 644 report.merge.assert_called_with(store.Portfolio.report)
607 file_report.assert_called_once_with(datetime.datetime(2018, 2, 25)) 645 file_report.assert_called_once_with(datetime.datetime(2018, 2, 25))
608 db_report.assert_called_once_with(datetime.datetime(2018, 2, 25)) 646 db_report.assert_called_once_with(datetime.datetime(2018, 2, 25))
647 redis_report.assert_not_called()
648
649 report.reset_mock()
650 m = market.Market(self.ccxt, self.market_args(report_redis=False),
651 redis_config="redis_config", user_id=1)
652 with self.subTest(redis_config="present", report_redis=False),\
653 mock.patch.object(m, "report") as report,\
654 mock.patch.object(m, "store_file_report") as file_report,\
655 mock.patch.object(m, "store_redis_report") as redis_report,\
656 mock.patch.object(m, "store_database_report") as db_report,\
657 mock.patch.object(market.datetime, "datetime") as time_mock:
658
659 time_mock.now.return_value = datetime.datetime(2018, 2, 25)
660
661 m.store_report()
662 redis_report.assert_not_called()
663
664 report.reset_mock()
665 m = market.Market(self.ccxt, self.market_args(report_redis=True),
666 user_id=1)
667 with self.subTest(redis_config="absent", report_redis=True),\
668 mock.patch.object(m, "report") as report,\
669 mock.patch.object(m, "store_file_report") as file_report,\
670 mock.patch.object(m, "store_redis_report") as redis_report,\
671 mock.patch.object(m, "store_database_report") as db_report,\
672 mock.patch.object(market.datetime, "datetime") as time_mock:
673
674 time_mock.now.return_value = datetime.datetime(2018, 2, 25)
675
676 m.store_report()
677 redis_report.assert_not_called()
678
679 report.reset_mock()
680 m = market.Market(self.ccxt, self.market_args(report_redis=True),
681 redis_config="redis_config", user_id=1)
682 with self.subTest(redis_config="present", report_redis=True),\
683 mock.patch.object(m, "report") as report,\
684 mock.patch.object(m, "store_file_report") as file_report,\
685 mock.patch.object(m, "store_redis_report") as redis_report,\
686 mock.patch.object(m, "store_database_report") as db_report,\
687 mock.patch.object(market.datetime, "datetime") as time_mock:
688
689 time_mock.now.return_value = datetime.datetime(2018, 2, 25)
690
691 m.store_report()
692 redis_report.assert_called_once_with(datetime.datetime(2018, 2, 25))
609 693
610 def test_print_tickers(self): 694 def test_print_tickers(self):
611 m = market.Market(self.ccxt, self.market_args()) 695 m = market.Market(self.ccxt, self.market_args())
diff --git a/tests/test_store.py b/tests/test_store.py
index ffd2645..df113b7 100644
--- a/tests/test_store.py
+++ b/tests/test_store.py
@@ -459,6 +459,13 @@ class ReportStoreTest(WebMockTestCase):
459 459
460 self.assertEqual({"foo": "bar", "date": mock.ANY, "user_id": None, "market_id": None}, result) 460 self.assertEqual({"foo": "bar", "date": mock.ANY, "user_id": None, "market_id": None}, result)
461 461
462 def test_add_redis_status(self):
463 report_store = market.ReportStore(self.m)
464 result = report_store.add_redis_status({"foo": "bar"})
465
466 self.assertEqual({"foo": "bar"}, result)
467 self.assertEqual(result, report_store.redis_status[0])
468
462 def test_set_verbose(self): 469 def test_set_verbose(self):
463 report_store = market.ReportStore(self.m) 470 report_store = market.ReportStore(self.m)
464 with self.subTest(verbose=True): 471 with self.subTest(verbose=True):
@@ -534,6 +541,20 @@ class ReportStoreTest(WebMockTestCase):
534 self.assertEqual(("date1", "type1", '{\n "foo": "bar",\n "bla": "bla"\n}'), logs[0]) 541 self.assertEqual(("date1", "type1", '{\n "foo": "bar",\n "bla": "bla"\n}'), logs[0])
535 self.assertEqual(("date2", "type2", '{\n "foo": "bar",\n "bla": "bla"\n}'), logs[1]) 542 self.assertEqual(("date2", "type2", '{\n "foo": "bar",\n "bla": "bla"\n}'), logs[1])
536 543
544 def test_to_json_redis(self):
545 report_store = market.ReportStore(self.m)
546 report_store.redis_status.append({
547 "type": "type1", "foo": "bar", "bla": "bla"
548 })
549 report_store.redis_status.append({
550 "type": "type2", "foo": "bar", "bla": "bla"
551 })
552 logs = list(report_store.to_json_redis())
553
554 self.assertEqual(2, len(logs))
555 self.assertEqual(("type1", '{"foo": "bar", "bla": "bla"}'), logs[0])
556 self.assertEqual(("type2", '{"foo": "bar", "bla": "bla"}'), logs[1])
557
537 @mock.patch.object(market.ReportStore, "print_log") 558 @mock.patch.object(market.ReportStore, "print_log")
538 @mock.patch.object(market.ReportStore, "add_log") 559 @mock.patch.object(market.ReportStore, "add_log")
539 def test_log_stage(self, add_log, print_log): 560 def test_log_stage(self, add_log, print_log):
@@ -559,7 +580,8 @@ class ReportStoreTest(WebMockTestCase):
559 580
560 @mock.patch.object(market.ReportStore, "print_log") 581 @mock.patch.object(market.ReportStore, "print_log")
561 @mock.patch.object(market.ReportStore, "add_log") 582 @mock.patch.object(market.ReportStore, "add_log")
562 def test_log_balances(self, add_log, print_log): 583 @mock.patch.object(market.ReportStore, "add_redis_status")
584 def test_log_balances(self, add_redis_status, add_log, print_log):
563 report_store = market.ReportStore(self.m) 585 report_store = market.ReportStore(self.m)
564 self.m.balances.as_json.return_value = "json" 586 self.m.balances.as_json.return_value = "json"
565 self.m.balances.all = { "FOO": "bar", "BAR": "baz" } 587 self.m.balances.all = { "FOO": "bar", "BAR": "baz" }
@@ -575,10 +597,16 @@ class ReportStoreTest(WebMockTestCase):
575 'balances': 'json', 597 'balances': 'json',
576 'tag': 'tag' 598 'tag': 'tag'
577 }) 599 })
600 add_redis_status.assert_called_once_with({
601 'type': 'balance',
602 'balances': 'json',
603 'tag': 'tag'
604 })
578 605
579 @mock.patch.object(market.ReportStore, "print_log") 606 @mock.patch.object(market.ReportStore, "print_log")
580 @mock.patch.object(market.ReportStore, "add_log") 607 @mock.patch.object(market.ReportStore, "add_log")
581 def test_log_tickers(self, add_log, print_log): 608 @mock.patch.object(market.ReportStore, "add_redis_status")
609 def test_log_tickers(self, add_redis_status, add_log, print_log):
582 report_store = market.ReportStore(self.m) 610 report_store = market.ReportStore(self.m)
583 amounts = { 611 amounts = {
584 "BTC": portfolio.Amount("BTC", 10), 612 "BTC": portfolio.Amount("BTC", 10),
@@ -603,6 +631,21 @@ class ReportStoreTest(WebMockTestCase):
603 }, 631 },
604 'total': D('10.3') 632 'total': D('10.3')
605 }) 633 })
634 add_redis_status.assert_called_once_with({
635 'type': 'tickers',
636 'compute_value': 'default',
637 'balance_type': 'total',
638 'currency': 'BTC',
639 'balances': {
640 'BTC': D('10'),
641 'ETH': D('0.3')
642 },
643 'rates': {
644 'BTC': None,
645 'ETH': D('0.1')
646 },
647 'total': D('10.3')
648 })
606 649
607 add_log.reset_mock() 650 add_log.reset_mock()
608 compute_value = lambda x: x["bid"] 651 compute_value = lambda x: x["bid"]