aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorIsmaël Bouya <ismael.bouya@normalesup.org>2018-05-02 01:39:35 +0200
committerIsmaël Bouya <ismael.bouya@normalesup.org>2018-05-02 01:39:35 +0200
commit30700830b6c0aaaa59c148ebd8edb6931040ed13 (patch)
tree8868074072e95d9b9119b36e3d6d66a70408775a /tests
parent2b1ee8f4d54fa1672510141a71a5817120ac031c (diff)
downloadTrader-30700830b6c0aaaa59c148ebd8edb6931040ed13.tar.gz
Trader-30700830b6c0aaaa59c148ebd8edb6931040ed13.tar.zst
Trader-30700830b6c0aaaa59c148ebd8edb6931040ed13.zip
Refactor databases access
Diffstat (limited to 'tests')
-rw-r--r--tests/helper.py4
-rw-r--r--tests/test_dbs.py108
-rw-r--r--tests/test_main.py107
-rw-r--r--tests/test_market.py90
4 files changed, 208 insertions, 101 deletions
diff --git a/tests/helper.py b/tests/helper.py
index b85bf3a..935e060 100644
--- a/tests/helper.py
+++ b/tests/helper.py
@@ -4,7 +4,7 @@ from decimal import Decimal as D
4from unittest import mock 4from unittest import mock
5import requests_mock 5import requests_mock
6from io import StringIO 6from io import StringIO
7import portfolio, market, main, store 7import portfolio, market, main, store, dbs
8 8
9__all__ = ["limits", "unittest", "WebMockTestCase", "mock", "D", 9__all__ = ["limits", "unittest", "WebMockTestCase", "mock", "D",
10 "StringIO"] 10 "StringIO"]
@@ -48,6 +48,8 @@ class WebMockTestCase(unittest.TestCase):
48 callback=None), 48 callback=None),
49 mock.patch.multiple(portfolio.Computation, 49 mock.patch.multiple(portfolio.Computation,
50 computations=portfolio.Computation.computations), 50 computations=portfolio.Computation.computations),
51 mock.patch.multiple(dbs,
52 redis=None, psql=None)
51 ] 53 ]
52 for patcher in self.patchers: 54 for patcher in self.patchers:
53 patcher.start() 55 patcher.start()
diff --git a/tests/test_dbs.py b/tests/test_dbs.py
new file mode 100644
index 0000000..157c423
--- /dev/null
+++ b/tests/test_dbs.py
@@ -0,0 +1,108 @@
1from .helper import *
2import dbs, main
3
4@unittest.skipUnless("unit" in limits, "Unit skipped")
5class DbsTest(WebMockTestCase):
6 @mock.patch.object(dbs, "psycopg2")
7 def test_connect_psql(self, psycopg2):
8 args = main.configargparse.Namespace(**{
9 "db_host": "host",
10 "db_port": "port",
11 "db_user": "user",
12 "db_password": "password",
13 "db_database": "database",
14 })
15 psycopg2.connect.return_value = "pg_connection"
16 dbs.connect_psql(args)
17
18 psycopg2.connect.assert_called_once_with(host="host",
19 port="port", user="user", password="password",
20 database="database")
21 self.assertEqual("pg_connection", dbs.psql)
22 with self.assertRaises(AttributeError):
23 args.db_password
24
25 psycopg2.connect.reset_mock()
26 args = main.configargparse.Namespace(**{
27 "db_host": "host",
28 "db_port": "port",
29 "db_user": "user",
30 "db_password": "password",
31 "db_database": "database",
32 })
33 dbs.connect_psql(args)
34 psycopg2.connect.assert_not_called()
35
36 @mock.patch.object(dbs, "_redis")
37 def test_connect_redis(self, redis):
38 with self.subTest(redis_host="tcp"):
39 args = main.configargparse.Namespace(**{
40 "redis_host": "host",
41 "redis_port": "port",
42 "redis_database": "database",
43 })
44 redis.Redis.return_value = "redis_connection"
45 dbs.connect_redis(args)
46
47 redis.Redis.assert_called_once_with(host="host",
48 port="port", db="database")
49 self.assertEqual("redis_connection", dbs.redis)
50 with self.assertRaises(AttributeError):
51 args.redis_database
52
53 redis.Redis.reset_mock()
54 args = main.configargparse.Namespace(**{
55 "redis_host": "host",
56 "redis_port": "port",
57 "redis_database": "database",
58 })
59 dbs.connect_redis(args)
60 redis.Redis.assert_not_called()
61
62 dbs.redis = None
63 with self.subTest(redis_host="socket"):
64 args = main.configargparse.Namespace(**{
65 "redis_host": "/run/foo",
66 "redis_port": "port",
67 "redis_database": "database",
68 })
69 redis.Redis.return_value = "redis_socket"
70 dbs.connect_redis(args)
71
72 redis.Redis.assert_called_once_with(unix_socket_path="/run/foo", db="database")
73 self.assertEqual("redis_socket", dbs.redis)
74
75 def test_redis_connected(self):
76 with self.subTest(redis=None):
77 dbs.redis = None
78 self.assertFalse(dbs.redis_connected())
79
80 with self.subTest(redis="mocked_true"):
81 dbs.redis = mock.Mock()
82 dbs.redis.ping.return_value = True
83 self.assertTrue(dbs.redis_connected())
84
85 with self.subTest(redis="mocked_false"):
86 dbs.redis = mock.Mock()
87 dbs.redis.ping.return_value = False
88 self.assertFalse(dbs.redis_connected())
89
90 with self.subTest(redis="mocked_raise"):
91 dbs.redis = mock.Mock()
92 dbs.redis.ping.side_effect = Exception("bouh")
93 self.assertFalse(dbs.redis_connected())
94
95 def test_psql_connected(self):
96 with self.subTest(psql=None):
97 dbs.psql = None
98 self.assertFalse(dbs.psql_connected())
99
100 with self.subTest(psql="connected"):
101 dbs.psql = mock.Mock()
102 dbs.psql.closed = 0
103 self.assertTrue(dbs.psql_connected())
104
105 with self.subTest(psql="not connected"):
106 dbs.psql = mock.Mock()
107 dbs.psql.closed = 3
108 self.assertFalse(dbs.psql_connected())
diff --git a/tests/test_main.py b/tests/test_main.py
index 55b1382..1864c06 100644
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -103,7 +103,6 @@ class MainTest(WebMockTestCase):
103 mock.patch("main.parse_config") as main_parse_config: 103 mock.patch("main.parse_config") as main_parse_config:
104 with self.subTest(debug=False): 104 with self.subTest(debug=False):
105 main_parse_args.return_value = self.market_args() 105 main_parse_args.return_value = self.market_args()
106 main_parse_config.return_value = ["pg_config", "redis_config"]
107 main_fetch_markets.return_value = [(1, {"key": "market_config"}, 3)] 106 main_fetch_markets.return_value = [(1, {"key": "market_config"}, 3)]
108 m = main.get_user_market("config_path.ini", 1) 107 m = main.get_user_market("config_path.ini", 1)
109 108
@@ -114,7 +113,6 @@ class MainTest(WebMockTestCase):
114 main_parse_args.reset_mock() 113 main_parse_args.reset_mock()
115 with self.subTest(debug=True): 114 with self.subTest(debug=True):
116 main_parse_args.return_value = self.market_args(debug=True) 115 main_parse_args.return_value = self.market_args(debug=True)
117 main_parse_config.return_value = ["pg_config", "redis_config"]
118 main_fetch_markets.return_value = [(1, {"key": "market_config"}, 3)] 116 main_fetch_markets.return_value = [(1, {"key": "market_config"}, 3)]
119 m = main.get_user_market("config_path.ini", 1, debug=True) 117 m = main.get_user_market("config_path.ini", 1, debug=True)
120 118
@@ -135,16 +133,16 @@ class MainTest(WebMockTestCase):
135 args_mock.after = "after" 133 args_mock.after = "after"
136 self.assertEqual("", stdout_mock.getvalue()) 134 self.assertEqual("", stdout_mock.getvalue())
137 135
138 main.process("config", 3, 1, args_mock, "pg_config", "redis_config") 136 main.process("config", 3, 1, args_mock)
139 137
140 market_mock.from_config.assert_has_calls([ 138 market_mock.from_config.assert_has_calls([
141 mock.call("config", args_mock, pg_config="pg_config", redis_config="redis_config", market_id=3, user_id=1), 139 mock.call("config", args_mock, market_id=3, user_id=1),
142 mock.call().process("action", before="before", after="after"), 140 mock.call().process("action", before="before", after="after"),
143 ]) 141 ])
144 142
145 with self.subTest(exception=True): 143 with self.subTest(exception=True):
146 market_mock.from_config.side_effect = Exception("boo") 144 market_mock.from_config.side_effect = Exception("boo")
147 main.process(3, "config", 1, args_mock, "pg_config", "redis_config") 145 main.process(3, "config", 1, args_mock)
148 self.assertEqual("Exception: boo\n", stdout_mock.getvalue()) 146 self.assertEqual("Exception: boo\n", stdout_mock.getvalue())
149 147
150 def test_main(self): 148 def test_main(self):
@@ -159,20 +157,18 @@ class MainTest(WebMockTestCase):
159 args_mock.user = "user" 157 args_mock.user = "user"
160 parse_args.return_value = args_mock 158 parse_args.return_value = args_mock
161 159
162 parse_config.return_value = ["pg_config", "redis_config"]
163
164 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]] 160 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]]
165 161
166 main.main(["Foo", "Bar"]) 162 main.main(["Foo", "Bar"])
167 163
168 parse_args.assert_called_with(["Foo", "Bar"]) 164 parse_args.assert_called_with(["Foo", "Bar"])
169 parse_config.assert_called_with(args_mock) 165 parse_config.assert_called_with(args_mock)
170 fetch_markets.assert_called_with("pg_config", "user") 166 fetch_markets.assert_called_with("user")
171 167
172 self.assertEqual(2, process.call_count) 168 self.assertEqual(2, process.call_count)
173 process.assert_has_calls([ 169 process.assert_has_calls([
174 mock.call("config1", 3, 1, args_mock, "pg_config", "redis_config"), 170 mock.call("config1", 3, 1, args_mock),
175 mock.call("config2", 1, 2, args_mock, "pg_config", "redis_config"), 171 mock.call("config2", 1, 2, args_mock),
176 ]) 172 ])
177 with self.subTest(parallel=True): 173 with self.subTest(parallel=True):
178 with mock.patch("main.parse_args") as parse_args,\ 174 with mock.patch("main.parse_args") as parse_args,\
@@ -187,24 +183,22 @@ class MainTest(WebMockTestCase):
187 args_mock.user = "user" 183 args_mock.user = "user"
188 parse_args.return_value = args_mock 184 parse_args.return_value = args_mock
189 185
190 parse_config.return_value = ["pg_config", "redis_config"]
191
192 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]] 186 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]]
193 187
194 main.main(["Foo", "Bar"]) 188 main.main(["Foo", "Bar"])
195 189
196 parse_args.assert_called_with(["Foo", "Bar"]) 190 parse_args.assert_called_with(["Foo", "Bar"])
197 parse_config.assert_called_with(args_mock) 191 parse_config.assert_called_with(args_mock)
198 fetch_markets.assert_called_with("pg_config", "user") 192 fetch_markets.assert_called_with("user")
199 193
200 stop.assert_called_once_with() 194 stop.assert_called_once_with()
201 start.assert_called_once_with() 195 start.assert_called_once_with()
202 self.assertEqual(2, process.call_count) 196 self.assertEqual(2, process.call_count)
203 process.assert_has_calls([ 197 process.assert_has_calls([
204 mock.call.__bool__(), 198 mock.call.__bool__(),
205 mock.call("config1", 3, 1, args_mock, "pg_config", "redis_config"), 199 mock.call("config1", 3, 1, args_mock),
206 mock.call.__bool__(), 200 mock.call.__bool__(),
207 mock.call("config2", 1, 2, args_mock, "pg_config", "redis_config"), 201 mock.call("config2", 1, 2, args_mock),
208 ]) 202 ])
209 with self.subTest(quiet=True): 203 with self.subTest(quiet=True):
210 with mock.patch("main.parse_args") as parse_args,\ 204 with mock.patch("main.parse_args") as parse_args,\
@@ -219,8 +213,6 @@ class MainTest(WebMockTestCase):
219 args_mock.user = "user" 213 args_mock.user = "user"
220 parse_args.return_value = args_mock 214 parse_args.return_value = args_mock
221 215
222 parse_config.return_value = ["pg_config", "redis_config"]
223
224 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]] 216 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]]
225 217
226 main.main(["Foo", "Bar"]) 218 main.main(["Foo", "Bar"])
@@ -240,8 +232,6 @@ class MainTest(WebMockTestCase):
240 args_mock.user = "user" 232 args_mock.user = "user"
241 parse_args.return_value = args_mock 233 parse_args.return_value = args_mock
242 234
243 parse_config.return_value = ["pg_config", "redis_config"]
244
245 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]] 235 fetch_markets.return_value = [[3, "config1", 1], [1, "config2", 2]]
246 236
247 main.main(["Foo", "Bar"]) 237 main.main(["Foo", "Bar"])
@@ -252,63 +242,57 @@ class MainTest(WebMockTestCase):
252 @mock.patch.object(main.sys, "exit") 242 @mock.patch.object(main.sys, "exit")
253 @mock.patch("main.os") 243 @mock.patch("main.os")
254 def test_parse_config(self, os, exit): 244 def test_parse_config(self, os, exit):
255 with self.subTest(report_path=None): 245 with self.subTest(report_path=None),\
246 mock.patch.object(main.dbs, "connect_psql") as psql,\
247 mock.patch.object(main.dbs, "connect_redis") as redis:
256 args = main.configargparse.Namespace(**{ 248 args = main.configargparse.Namespace(**{
257 "db_host": "host", 249 "db_host": "host",
258 "db_port": "port",
259 "db_user": "user",
260 "db_password": "password",
261 "db_database": "database",
262 "redis_host": "rhost", 250 "redis_host": "rhost",
263 "redis_port": "rport",
264 "redis_database": "rdb",
265 "report_path": None, 251 "report_path": None,
266 }) 252 })
267 253
268 db_config, redis_config = main.parse_config(args) 254 main.parse_config(args)
269 self.assertEqual({ "host": "host", "port": "port", "user": 255 psql.assert_called_once_with(args)
270 "user", "password": "password", "database": "database" 256 redis.assert_called_once_with(args)
271 }, db_config) 257
272 self.assertEqual({ "host": "rhost", "port": "rport", "db": 258 with self.subTest(report_path=None, db=None),\
273 "rdb"}, redis_config) 259 mock.patch.object(main.dbs, "connect_psql") as psql,\
260 mock.patch.object(main.dbs, "connect_redis") as redis:
261 args = main.configargparse.Namespace(**{
262 "db_host": None,
263 "redis_host": "rhost",
264 "report_path": None,
265 })
274 266
275 with self.assertRaises(AttributeError): 267 main.parse_config(args)
276 args.db_password 268 psql.assert_not_called()
277 with self.assertRaises(AttributeError): 269 redis.assert_called_once_with(args)
278 args.redis_host
279 270
280 with self.subTest(redis_host="socket"): 271 with self.subTest(report_path=None, redis=None),\
272 mock.patch.object(main.dbs, "connect_psql") as psql,\
273 mock.patch.object(main.dbs, "connect_redis") as redis:
281 args = main.configargparse.Namespace(**{ 274 args = main.configargparse.Namespace(**{
282 "db_host": "host", 275 "db_host": "host",
283 "db_port": "port", 276 "redis_host": None,
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, 277 "report_path": None,
291 }) 278 })
292 279
293 db_config, redis_config = main.parse_config(args) 280 main.parse_config(args)
294 self.assertEqual({ "unix_socket_path": "/run/foo", "db": "rdb"}, redis_config) 281 redis.assert_not_called()
282 psql.assert_called_once_with(args)
295 283
296 with self.subTest(report_path="present"): 284 with self.subTest(report_path="present"),\
285 mock.patch.object(main.dbs, "connect_psql") as psql,\
286 mock.patch.object(main.dbs, "connect_redis") as redis:
297 args = main.configargparse.Namespace(**{ 287 args = main.configargparse.Namespace(**{
298 "db_host": "host", 288 "db_host": "host",
299 "db_port": "port",
300 "db_user": "user",
301 "db_password": "password",
302 "db_database": "database",
303 "redis_host": "rhost", 289 "redis_host": "rhost",
304 "redis_port": "rport",
305 "redis_database": "rdb",
306 "report_path": "report_path", 290 "report_path": "report_path",
307 }) 291 })
308 292
309 os.path.exists.return_value = False 293 os.path.exists.return_value = False
310 294
311 result = main.parse_config(args) 295 main.parse_config(args)
312 296
313 os.path.exists.assert_called_once_with("report_path") 297 os.path.exists.assert_called_once_with("report_path")
314 os.makedirs.assert_called_once_with("report_path") 298 os.makedirs.assert_called_once_with("report_path")
@@ -331,29 +315,24 @@ class MainTest(WebMockTestCase):
331 mock.patch('sys.stderr', new_callable=StringIO) as stdout_mock: 315 mock.patch('sys.stderr', new_callable=StringIO) as stdout_mock:
332 args = main.parse_args(["--config", "foo.bar"]) 316 args = main.parse_args(["--config", "foo.bar"])
333 317
334 @mock.patch.object(main, "psycopg2") 318 @mock.patch.object(main.dbs, "psql")
335 def test_fetch_markets(self, psycopg2): 319 def test_fetch_markets(self, psql):
336 connect_mock = mock.Mock()
337 cursor_mock = mock.MagicMock() 320 cursor_mock = mock.MagicMock()
338 cursor_mock.__iter__.return_value = ["row_1", "row_2"] 321 cursor_mock.__iter__.return_value = ["row_1", "row_2"]
339 322
340 connect_mock.cursor.return_value = cursor_mock 323 psql.cursor.return_value = cursor_mock
341 psycopg2.connect.return_value = connect_mock
342 324
343 with self.subTest(user=None): 325 with self.subTest(user=None):
344 rows = list(main.fetch_markets({"foo": "bar"}, None)) 326 rows = list(main.fetch_markets(None))
345 327
346 psycopg2.connect.assert_called_once_with(foo="bar")
347 cursor_mock.execute.assert_called_once_with("SELECT id,config,user_id FROM market_configs") 328 cursor_mock.execute.assert_called_once_with("SELECT id,config,user_id FROM market_configs")
348 329
349 self.assertEqual(["row_1", "row_2"], rows) 330 self.assertEqual(["row_1", "row_2"], rows)
350 331
351 psycopg2.connect.reset_mock()
352 cursor_mock.execute.reset_mock() 332 cursor_mock.execute.reset_mock()
353 with self.subTest(user=1): 333 with self.subTest(user=1):
354 rows = list(main.fetch_markets({"foo": "bar"}, 1)) 334 rows = list(main.fetch_markets(1))
355 335
356 psycopg2.connect.assert_called_once_with(foo="bar")
357 cursor_mock.execute.assert_called_once_with("SELECT id,config,user_id FROM market_configs WHERE user_id = %s", 1) 336 cursor_mock.execute.assert_called_once_with("SELECT id,config,user_id FROM market_configs WHERE user_id = %s", 1)
358 337
359 self.assertEqual(["row_1", "row_2"], rows) 338 self.assertEqual(["row_1", "row_2"], rows)
diff --git a/tests/test_market.py b/tests/test_market.py
index 6a3322c..ab3cd5e 100644
--- a/tests/test_market.py
+++ b/tests/test_market.py
@@ -1,5 +1,5 @@
1from .helper import * 1from .helper import *
2import market, store, portfolio 2import market, store, portfolio, dbs
3import datetime 3import datetime
4 4
5@unittest.skipUnless("unit" in limits, "Unit skipped") 5@unittest.skipUnless("unit" in limits, "Unit skipped")
@@ -595,13 +595,11 @@ class MarketTest(WebMockTestCase):
595 595
596 self.assertRegex(stdout_mock.getvalue(), "impossible to store report file: FileNotFoundError;") 596 self.assertRegex(stdout_mock.getvalue(), "impossible to store report file: FileNotFoundError;")
597 597
598 @mock.patch.object(market, "psycopg2") 598 @mock.patch.object(dbs, "psql")
599 def test_store_database_report(self, psycopg2): 599 def test_store_database_report(self, psql):
600 connect_mock = mock.Mock()
601 cursor_mock = mock.MagicMock() 600 cursor_mock = mock.MagicMock()
602 601
603 connect_mock.cursor.return_value = cursor_mock 602 psql.cursor.return_value = cursor_mock
604 psycopg2.connect.return_value = connect_mock
605 m = market.Market(self.ccxt, self.market_args(), 603 m = market.Market(self.ccxt, self.market_args(),
606 pg_config={"config": "pg_config"}, user_id=1) 604 pg_config={"config": "pg_config"}, user_id=1)
607 cursor_mock.fetchone.return_value = [42] 605 cursor_mock.fetchone.return_value = [42]
@@ -613,7 +611,7 @@ class MarketTest(WebMockTestCase):
613 ("date2", "type2", "payload2"), 611 ("date2", "type2", "payload2"),
614 ] 612 ]
615 m.store_database_report(datetime.datetime(2018, 3, 24)) 613 m.store_database_report(datetime.datetime(2018, 3, 24))
616 connect_mock.assert_has_calls([ 614 psql.assert_has_calls([
617 mock.call.cursor(), 615 mock.call.cursor(),
618 mock.call.cursor().execute('INSERT INTO reports("date", "market_config_id", "debug") VALUES (%s, %s, %s) RETURNING id;', (datetime.datetime(2018, 3, 24), None, False)), 616 mock.call.cursor().execute('INSERT INTO reports("date", "market_config_id", "debug") VALUES (%s, %s, %s) RETURNING id;', (datetime.datetime(2018, 3, 24), None, False)),
619 mock.call.cursor().fetchone(), 617 mock.call.cursor().fetchone(),
@@ -621,21 +619,16 @@ class MarketTest(WebMockTestCase):
621 mock.call.cursor().execute('INSERT INTO report_lines("date", "report_id", "type", "payload") VALUES (%s, %s, %s, %s);', ('date2', 42, 'type2', 'payload2')), 619 mock.call.cursor().execute('INSERT INTO report_lines("date", "report_id", "type", "payload") VALUES (%s, %s, %s, %s);', ('date2', 42, 'type2', 'payload2')),
622 mock.call.commit(), 620 mock.call.commit(),
623 mock.call.cursor().close(), 621 mock.call.cursor().close(),
624 mock.call.close()
625 ]) 622 ])
626 623
627 connect_mock.reset_mock()
628 with self.subTest(error=True),\ 624 with self.subTest(error=True),\
629 mock.patch('sys.stdout', new_callable=StringIO) as stdout_mock: 625 mock.patch('sys.stdout', new_callable=StringIO) as stdout_mock:
630 psycopg2.connect.side_effect = Exception("Bouh") 626 psql.cursor.side_effect = Exception("Bouh")
631 m.store_database_report(datetime.datetime(2018, 3, 24)) 627 m.store_database_report(datetime.datetime(2018, 3, 24))
632 self.assertEqual(stdout_mock.getvalue(), "impossible to store report to database: Exception; Bouh\n") 628 self.assertEqual(stdout_mock.getvalue(), "impossible to store report to database: Exception; Bouh\n")
633 629
634 @mock.patch.object(market, "redis") 630 @mock.patch.object(dbs, "redis")
635 def test_store_redis_report(self, redis): 631 def test_store_redis_report(self, redis):
636 connect_mock = mock.Mock()
637 redis.Redis.return_value = connect_mock
638
639 m = market.Market(self.ccxt, self.market_args(), 632 m = market.Market(self.ccxt, self.market_args(),
640 redis_config={"config": "redis_config"}, market_id=1) 633 redis_config={"config": "redis_config"}, market_id=1)
641 634
@@ -646,7 +639,7 @@ class MarketTest(WebMockTestCase):
646 ("type2", "payload2"), 639 ("type2", "payload2"),
647 ] 640 ]
648 m.store_redis_report(datetime.datetime(2018, 3, 24)) 641 m.store_redis_report(datetime.datetime(2018, 3, 24))
649 connect_mock.assert_has_calls([ 642 redis.assert_has_calls([
650 mock.call.set("/cryptoportfolio/1/2018-03-24T00:00:00/type1", "payload1", ex=31*24*60*60), 643 mock.call.set("/cryptoportfolio/1/2018-03-24T00:00:00/type1", "payload1", ex=31*24*60*60),
651 mock.call.set("/cryptoportfolio/1/latest/type1", "payload1"), 644 mock.call.set("/cryptoportfolio/1/latest/type1", "payload1"),
652 mock.call.set("/cryptoportfolio/1/2018-03-24T00:00:00/type2", "payload2", ex=31*24*60*60), 645 mock.call.set("/cryptoportfolio/1/2018-03-24T00:00:00/type2", "payload2", ex=31*24*60*60),
@@ -654,20 +647,24 @@ class MarketTest(WebMockTestCase):
654 mock.call.set("/cryptoportfolio/1/latest/date", "2018-03-24T00:00:00"), 647 mock.call.set("/cryptoportfolio/1/latest/date", "2018-03-24T00:00:00"),
655 ]) 648 ])
656 649
657 connect_mock.reset_mock() 650 redis.reset_mock()
658 with self.subTest(error=True),\ 651 with self.subTest(error=True),\
659 mock.patch('sys.stdout', new_callable=StringIO) as stdout_mock: 652 mock.patch('sys.stdout', new_callable=StringIO) as stdout_mock:
660 redis.Redis.side_effect = Exception("Bouh") 653 redis.set.side_effect = Exception("Bouh")
661 m.store_redis_report(datetime.datetime(2018, 3, 24)) 654 m.store_redis_report(datetime.datetime(2018, 3, 24))
662 self.assertEqual(stdout_mock.getvalue(), "impossible to store report to redis: Exception; Bouh\n") 655 self.assertEqual(stdout_mock.getvalue(), "impossible to store report to redis: Exception; Bouh\n")
663 656
664 def test_store_report(self): 657 def test_store_report(self):
665 m = market.Market(self.ccxt, self.market_args(report_db=False), user_id=1) 658 m = market.Market(self.ccxt, self.market_args(report_db=False), user_id=1)
666 with self.subTest(file=None, pg_config=None),\ 659 with self.subTest(file=None, pg_connected=None),\
660 mock.patch.object(dbs, "psql_connected") as psql,\
661 mock.patch.object(dbs, "redis_connected") as redis,\
667 mock.patch.object(m, "report") as report,\ 662 mock.patch.object(m, "report") as report,\
668 mock.patch.object(m, "store_database_report") as db_report,\ 663 mock.patch.object(m, "store_database_report") as db_report,\
669 mock.patch.object(m, "store_redis_report") as redis_report,\ 664 mock.patch.object(m, "store_redis_report") as redis_report,\
670 mock.patch.object(m, "store_file_report") as file_report: 665 mock.patch.object(m, "store_file_report") as file_report:
666 psql.return_value = False
667 redis.return_value = False
671 m.store_report() 668 m.store_report()
672 report.merge.assert_called_with(store.Portfolio.report) 669 report.merge.assert_called_with(store.Portfolio.report)
673 670
@@ -677,13 +674,16 @@ class MarketTest(WebMockTestCase):
677 674
678 report.reset_mock() 675 report.reset_mock()
679 m = market.Market(self.ccxt, self.market_args(report_db=False, report_path="present"), user_id=1) 676 m = market.Market(self.ccxt, self.market_args(report_db=False, report_path="present"), user_id=1)
680 with self.subTest(file="present", pg_config=None),\ 677 with self.subTest(file="present", pg_connected=None),\
678 mock.patch.object(dbs, "psql_connected") as psql,\
679 mock.patch.object(dbs, "redis_connected") as redis,\
681 mock.patch.object(m, "report") as report,\ 680 mock.patch.object(m, "report") as report,\
682 mock.patch.object(m, "store_file_report") as file_report,\ 681 mock.patch.object(m, "store_file_report") as file_report,\
683 mock.patch.object(m, "store_redis_report") as redis_report,\ 682 mock.patch.object(m, "store_redis_report") as redis_report,\
684 mock.patch.object(m, "store_database_report") as db_report,\ 683 mock.patch.object(m, "store_database_report") as db_report,\
685 mock.patch.object(market.datetime, "datetime") as time_mock: 684 mock.patch.object(market.datetime, "datetime") as time_mock:
686 685 psql.return_value = False
686 redis.return_value = False
687 time_mock.now.return_value = datetime.datetime(2018, 2, 25) 687 time_mock.now.return_value = datetime.datetime(2018, 2, 25)
688 688
689 m.store_report() 689 m.store_report()
@@ -695,13 +695,16 @@ class MarketTest(WebMockTestCase):
695 695
696 report.reset_mock() 696 report.reset_mock()
697 m = market.Market(self.ccxt, self.market_args(report_db=True, report_path="present"), user_id=1) 697 m = market.Market(self.ccxt, self.market_args(report_db=True, report_path="present"), user_id=1)
698 with self.subTest(file="present", pg_config=None, report_db=True),\ 698 with self.subTest(file="present", pg_connected=None, report_db=True),\
699 mock.patch.object(dbs, "psql_connected") as psql,\
700 mock.patch.object(dbs, "redis_connected") as redis,\
699 mock.patch.object(m, "report") as report,\ 701 mock.patch.object(m, "report") as report,\
700 mock.patch.object(m, "store_file_report") as file_report,\ 702 mock.patch.object(m, "store_file_report") as file_report,\
701 mock.patch.object(m, "store_redis_report") as redis_report,\ 703 mock.patch.object(m, "store_redis_report") as redis_report,\
702 mock.patch.object(m, "store_database_report") as db_report,\ 704 mock.patch.object(m, "store_database_report") as db_report,\
703 mock.patch.object(market.datetime, "datetime") as time_mock: 705 mock.patch.object(market.datetime, "datetime") as time_mock:
704 706 psql.return_value = False
707 redis.return_value = False
705 time_mock.now.return_value = datetime.datetime(2018, 2, 25) 708 time_mock.now.return_value = datetime.datetime(2018, 2, 25)
706 709
707 m.store_report() 710 m.store_report()
@@ -712,14 +715,17 @@ class MarketTest(WebMockTestCase):
712 redis_report.assert_not_called() 715 redis_report.assert_not_called()
713 716
714 report.reset_mock() 717 report.reset_mock()
715 m = market.Market(self.ccxt, self.market_args(report_db=True), pg_config="present", user_id=1) 718 m = market.Market(self.ccxt, self.market_args(report_db=True), user_id=1)
716 with self.subTest(file=None, pg_config="present"),\ 719 with self.subTest(file=None, pg_connected=True),\
720 mock.patch.object(dbs, "psql_connected") as psql,\
721 mock.patch.object(dbs, "redis_connected") as redis,\
717 mock.patch.object(m, "report") as report,\ 722 mock.patch.object(m, "report") as report,\
718 mock.patch.object(m, "store_file_report") as file_report,\ 723 mock.patch.object(m, "store_file_report") as file_report,\
719 mock.patch.object(m, "store_redis_report") as redis_report,\ 724 mock.patch.object(m, "store_redis_report") as redis_report,\
720 mock.patch.object(m, "store_database_report") as db_report,\ 725 mock.patch.object(m, "store_database_report") as db_report,\
721 mock.patch.object(market.datetime, "datetime") as time_mock: 726 mock.patch.object(market.datetime, "datetime") as time_mock:
722 727 psql.return_value = True
728 redis.return_value = False
723 time_mock.now.return_value = datetime.datetime(2018, 2, 25) 729 time_mock.now.return_value = datetime.datetime(2018, 2, 25)
724 730
725 m.store_report() 731 m.store_report()
@@ -731,14 +737,17 @@ class MarketTest(WebMockTestCase):
731 737
732 report.reset_mock() 738 report.reset_mock()
733 m = market.Market(self.ccxt, self.market_args(report_db=True, report_path="present"), 739 m = market.Market(self.ccxt, self.market_args(report_db=True, report_path="present"),
734 pg_config="pg_config", user_id=1) 740 user_id=1)
735 with self.subTest(file="present", pg_config="present"),\ 741 with self.subTest(file="present", pg_connected=True),\
742 mock.patch.object(dbs, "psql_connected") as psql,\
743 mock.patch.object(dbs, "redis_connected") as redis,\
736 mock.patch.object(m, "report") as report,\ 744 mock.patch.object(m, "report") as report,\
737 mock.patch.object(m, "store_file_report") as file_report,\ 745 mock.patch.object(m, "store_file_report") as file_report,\
738 mock.patch.object(m, "store_redis_report") as redis_report,\ 746 mock.patch.object(m, "store_redis_report") as redis_report,\
739 mock.patch.object(m, "store_database_report") as db_report,\ 747 mock.patch.object(m, "store_database_report") as db_report,\
740 mock.patch.object(market.datetime, "datetime") as time_mock: 748 mock.patch.object(market.datetime, "datetime") as time_mock:
741 749 psql.return_value = True
750 redis.return_value = False
742 time_mock.now.return_value = datetime.datetime(2018, 2, 25) 751 time_mock.now.return_value = datetime.datetime(2018, 2, 25)
743 752
744 m.store_report() 753 m.store_report()
@@ -750,14 +759,17 @@ class MarketTest(WebMockTestCase):
750 759
751 report.reset_mock() 760 report.reset_mock()
752 m = market.Market(self.ccxt, self.market_args(report_redis=False), 761 m = market.Market(self.ccxt, self.market_args(report_redis=False),
753 redis_config="redis_config", user_id=1) 762 user_id=1)
754 with self.subTest(redis_config="present", report_redis=False),\ 763 with self.subTest(redis_connected=True, report_redis=False),\
764 mock.patch.object(dbs, "psql_connected") as psql,\
765 mock.patch.object(dbs, "redis_connected") as redis,\
755 mock.patch.object(m, "report") as report,\ 766 mock.patch.object(m, "report") as report,\
756 mock.patch.object(m, "store_file_report") as file_report,\ 767 mock.patch.object(m, "store_file_report") as file_report,\
757 mock.patch.object(m, "store_redis_report") as redis_report,\ 768 mock.patch.object(m, "store_redis_report") as redis_report,\
758 mock.patch.object(m, "store_database_report") as db_report,\ 769 mock.patch.object(m, "store_database_report") as db_report,\
759 mock.patch.object(market.datetime, "datetime") as time_mock: 770 mock.patch.object(market.datetime, "datetime") as time_mock:
760 771 psql.return_value = False
772 redis.return_value = True
761 time_mock.now.return_value = datetime.datetime(2018, 2, 25) 773 time_mock.now.return_value = datetime.datetime(2018, 2, 25)
762 774
763 m.store_report() 775 m.store_report()
@@ -766,13 +778,16 @@ class MarketTest(WebMockTestCase):
766 report.reset_mock() 778 report.reset_mock()
767 m = market.Market(self.ccxt, self.market_args(report_redis=True), 779 m = market.Market(self.ccxt, self.market_args(report_redis=True),
768 user_id=1) 780 user_id=1)
769 with self.subTest(redis_config="absent", report_redis=True),\ 781 with self.subTest(redis_connected=False, report_redis=True),\
782 mock.patch.object(dbs, "psql_connected") as psql,\
783 mock.patch.object(dbs, "redis_connected") as redis,\
770 mock.patch.object(m, "report") as report,\ 784 mock.patch.object(m, "report") as report,\
771 mock.patch.object(m, "store_file_report") as file_report,\ 785 mock.patch.object(m, "store_file_report") as file_report,\
772 mock.patch.object(m, "store_redis_report") as redis_report,\ 786 mock.patch.object(m, "store_redis_report") as redis_report,\
773 mock.patch.object(m, "store_database_report") as db_report,\ 787 mock.patch.object(m, "store_database_report") as db_report,\
774 mock.patch.object(market.datetime, "datetime") as time_mock: 788 mock.patch.object(market.datetime, "datetime") as time_mock:
775 789 psql.return_value = False
790 redis.return_value = False
776 time_mock.now.return_value = datetime.datetime(2018, 2, 25) 791 time_mock.now.return_value = datetime.datetime(2018, 2, 25)
777 792
778 m.store_report() 793 m.store_report()
@@ -780,14 +795,17 @@ class MarketTest(WebMockTestCase):
780 795
781 report.reset_mock() 796 report.reset_mock()
782 m = market.Market(self.ccxt, self.market_args(report_redis=True), 797 m = market.Market(self.ccxt, self.market_args(report_redis=True),
783 redis_config="redis_config", user_id=1) 798 user_id=1)
784 with self.subTest(redis_config="present", report_redis=True),\ 799 with self.subTest(redis_connected=True, report_redis=True),\
800 mock.patch.object(dbs, "psql_connected") as psql,\
801 mock.patch.object(dbs, "redis_connected") as redis,\
785 mock.patch.object(m, "report") as report,\ 802 mock.patch.object(m, "report") as report,\
786 mock.patch.object(m, "store_file_report") as file_report,\ 803 mock.patch.object(m, "store_file_report") as file_report,\
787 mock.patch.object(m, "store_redis_report") as redis_report,\ 804 mock.patch.object(m, "store_redis_report") as redis_report,\
788 mock.patch.object(m, "store_database_report") as db_report,\ 805 mock.patch.object(m, "store_database_report") as db_report,\
789 mock.patch.object(market.datetime, "datetime") as time_mock: 806 mock.patch.object(market.datetime, "datetime") as time_mock:
790 807 psql.return_value = False
808 redis.return_value = True
791 time_mock.now.return_value = datetime.datetime(2018, 2, 25) 809 time_mock.now.return_value = datetime.datetime(2018, 2, 25)
792 810
793 m.store_report() 811 m.store_report()