forked from RedisJSON/RedisJSON
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path__init__.py
78 lines (60 loc) · 2.02 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import subprocess
import socket
import tempfile
import redis
import time
import os
import itertools
def get_random_port():
sock = socket.socket()
sock.listen(0)
_, port = sock.getsockname()
sock.close()
return port
class DisposableRedis(object):
def __init__(self, port=None, path='redis-server', **extra_args):
"""
:param port: port number to start the redis server on. Specify none to automatically generate
:type port: int|None
:param extra_args: any extra arguments kwargs will be passed to redis server as --key val
"""
self._port = port
# this will hold the actual port the redis is listening on. It's equal to `_port` unless `_port` is None
# in that case `port` is randomly generated
self.port = None
self.extra_args = list(itertools.chain(
*(('--%s'%k, v) for k, v in extra_args.items())
))
self.path = path
def __enter__(self):
if self._port is None:
self.port = get_random_port()
else:
self.port = self._port
args = [self.path,
'--port', str(self.port),
'--dir', tempfile.gettempdir(),
'--save', ''] + self.extra_args
self.process = subprocess.Popen(
args,
#cwd=os.getcwd(),
stdin=subprocess.PIPE,
stdout=open(os.devnull, 'w')
)
while True:
try:
self.client().ping()
break
except redis.ConnectionError:
self.process.poll()
if self.process.returncode is not None:
raise RuntimeError("Process has exited")
time.sleep(0.1)
return self.client()
def __exit__(self, exc_type, exc_val, exc_tb):
self.process.terminate()
def client(self):
"""
:rtype: redis.StrictRedis
"""
return redis.StrictRedis(port=self.port)