RLTest 0.7.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- RLTest/Enterprise/CcsMock.py +183 -0
- RLTest/Enterprise/Dmc.py +47 -0
- RLTest/Enterprise/EnterpriseClusterEnv.py +158 -0
- RLTest/Enterprise/__init__.py +5 -0
- RLTest/Enterprise/binaryrepo.py +71 -0
- RLTest/__init__.py +10 -0
- RLTest/__main__.py +1026 -0
- RLTest/_version.py +8 -0
- RLTest/debuggers.py +81 -0
- RLTest/env.py +646 -0
- RLTest/exists_redis.py +122 -0
- RLTest/loader.py +174 -0
- RLTest/random_port.py +63 -0
- RLTest/redis_cluster.py +241 -0
- RLTest/redis_enterprise_cluster.py +127 -0
- RLTest/redis_std.py +649 -0
- RLTest/utils.py +181 -0
- rltest-0.7.14.dist-info/LICENSE +29 -0
- rltest-0.7.14.dist-info/METADATA +296 -0
- rltest-0.7.14.dist-info/RECORD +22 -0
- rltest-0.7.14.dist-info/WHEEL +4 -0
- rltest-0.7.14.dist-info/entry_points.txt +3 -0
RLTest/env.py
ADDED
|
@@ -0,0 +1,646 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
from __future__ import print_function
|
|
3
|
+
|
|
4
|
+
import contextlib
|
|
5
|
+
import inspect
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
import unittest
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
11
|
+
from .exists_redis import ExistsRedisEnv
|
|
12
|
+
from .redis_cluster import ClusterEnv
|
|
13
|
+
from .redis_enterprise_cluster import EnterpriseRedisClusterEnv
|
|
14
|
+
from .redis_std import StandardEnv
|
|
15
|
+
from .utils import Colors, expandBinary, fix_modules, fix_modulesArgs
|
|
16
|
+
from packaging import version
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TestAssertionFailure(Exception):
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def genDeprecated(name, target):
|
|
24
|
+
def method(*argc, **nargs):
|
|
25
|
+
warnings.warn('%s is deprecated, use %s instead' % (str(name), str(target)), DeprecationWarning)
|
|
26
|
+
return target(*argc, **nargs)
|
|
27
|
+
return method
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Query:
|
|
31
|
+
def __init__(self, env, *query, **options):
|
|
32
|
+
self.query = query
|
|
33
|
+
self.options = options
|
|
34
|
+
self.env = env
|
|
35
|
+
self.errorRaised = False
|
|
36
|
+
self._evaluate()
|
|
37
|
+
|
|
38
|
+
def _evaluate(self):
|
|
39
|
+
try:
|
|
40
|
+
self.res = self.env.cmd(*self.query, **self.options)
|
|
41
|
+
except Exception as e:
|
|
42
|
+
self.res = str(e)
|
|
43
|
+
self.errorRaised = True
|
|
44
|
+
|
|
45
|
+
def _prettyPrint(self, result, prefix='\t'):
|
|
46
|
+
if type(result) is list:
|
|
47
|
+
print(prefix + '[')
|
|
48
|
+
for r in result:
|
|
49
|
+
self._prettyPrint(r, prefix + '\t')
|
|
50
|
+
print(prefix + ']')
|
|
51
|
+
return
|
|
52
|
+
print(prefix + str(result))
|
|
53
|
+
|
|
54
|
+
def prettyPrint(self):
|
|
55
|
+
self._prettyPrint(self.res)
|
|
56
|
+
return self
|
|
57
|
+
|
|
58
|
+
def debugPrint(self):
|
|
59
|
+
self.env.debugPrint('query: %s, result: %s' % (self.query, self.res), force=True)
|
|
60
|
+
return self
|
|
61
|
+
|
|
62
|
+
def apply(self, fn):
|
|
63
|
+
self.res = fn(self.res)
|
|
64
|
+
return self
|
|
65
|
+
|
|
66
|
+
def map(self, fn):
|
|
67
|
+
self.res = list(map(fn, self.res))
|
|
68
|
+
return self
|
|
69
|
+
|
|
70
|
+
def equal(self, expected):
|
|
71
|
+
self.env.assertEqual(self.res, expected, 1)
|
|
72
|
+
return self
|
|
73
|
+
|
|
74
|
+
def noEqual(self, expected):
|
|
75
|
+
self.env.assertNotEqual(self.res, expected, 1)
|
|
76
|
+
return self
|
|
77
|
+
|
|
78
|
+
def true(self):
|
|
79
|
+
self.env.assertTrue(self.res, 1)
|
|
80
|
+
return self
|
|
81
|
+
|
|
82
|
+
def false(self):
|
|
83
|
+
self.env.assertFalse(self.res, 1)
|
|
84
|
+
return self
|
|
85
|
+
|
|
86
|
+
def ok(self):
|
|
87
|
+
self.env.assertEqual(self.res, 'OK', 1)
|
|
88
|
+
return self
|
|
89
|
+
|
|
90
|
+
def contains(self, val):
|
|
91
|
+
self.env.assertContains(val, self.res, 1)
|
|
92
|
+
return self
|
|
93
|
+
|
|
94
|
+
def notContains(self, val):
|
|
95
|
+
self.env.assertNotContains(val, self.res, 1)
|
|
96
|
+
return self
|
|
97
|
+
|
|
98
|
+
def error(self):
|
|
99
|
+
self.env.assertTrue(self.errorRaised, 1)
|
|
100
|
+
return self
|
|
101
|
+
|
|
102
|
+
def noError(self):
|
|
103
|
+
self.env.assertFalse(self.errorRaised, 1)
|
|
104
|
+
return self
|
|
105
|
+
|
|
106
|
+
raiseError = genDeprecated('raiseError', error)
|
|
107
|
+
notRaiseError = genDeprecated('notRaiseError', noError)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class Defaults:
|
|
111
|
+
module = None
|
|
112
|
+
module_args = None
|
|
113
|
+
|
|
114
|
+
env = 'oss'
|
|
115
|
+
env_factory = lambda *args, **kwargs: Env(*args, **kwargs)
|
|
116
|
+
binary = 'redis-server'
|
|
117
|
+
proxy_binary = None
|
|
118
|
+
re_binary = None
|
|
119
|
+
re_libdir = None
|
|
120
|
+
decode_responses = False
|
|
121
|
+
use_aof = False
|
|
122
|
+
use_rdb_preamble = True
|
|
123
|
+
use_TLS = False
|
|
124
|
+
tls_cert_file = None
|
|
125
|
+
tls_key_file = None
|
|
126
|
+
tls_ca_cert_file = None
|
|
127
|
+
tls_passphrase = None
|
|
128
|
+
debugger = None
|
|
129
|
+
sanitizer = None
|
|
130
|
+
debug_print = False
|
|
131
|
+
debug_pause = False
|
|
132
|
+
no_capture_output = False
|
|
133
|
+
print_verbose_information_on_failure = False
|
|
134
|
+
no_log = False
|
|
135
|
+
exit_on_failure = False
|
|
136
|
+
verbose = 0
|
|
137
|
+
logdir = None
|
|
138
|
+
loglevel = None
|
|
139
|
+
use_slaves = False
|
|
140
|
+
num_shards = 1
|
|
141
|
+
external_addr = 'localhost:6379'
|
|
142
|
+
use_unix = False
|
|
143
|
+
randomize_ports = False
|
|
144
|
+
oss_password = None
|
|
145
|
+
cluster_node_timeout = None
|
|
146
|
+
curr_test_name = None
|
|
147
|
+
port = 6379
|
|
148
|
+
enable_debug_command = False
|
|
149
|
+
enable_protected_configs = False
|
|
150
|
+
enable_module_command = False
|
|
151
|
+
terminate_retries = None
|
|
152
|
+
terminate_retry_secs = None
|
|
153
|
+
protocol = 2
|
|
154
|
+
redis_config_file = None
|
|
155
|
+
|
|
156
|
+
def getKwargs(self):
|
|
157
|
+
kwargs = {
|
|
158
|
+
'modulePath': self.module,
|
|
159
|
+
'moduleArgs': self.module_args,
|
|
160
|
+
'port': self.port,
|
|
161
|
+
'useSlaves': self.use_slaves,
|
|
162
|
+
'useAof': self.use_aof,
|
|
163
|
+
'useRdbPreamble': self.use_rdb_preamble,
|
|
164
|
+
'dbDirPath': self.logdir,
|
|
165
|
+
'debugger': self.debugger,
|
|
166
|
+
'sanitizer': self.sanitizer,
|
|
167
|
+
'noCatch': self.no_capture_output,
|
|
168
|
+
'noLog': self.no_log,
|
|
169
|
+
'verbose': self.verbose,
|
|
170
|
+
'useTLS': self.use_TLS,
|
|
171
|
+
'tlsCertFile': self.tls_cert_file,
|
|
172
|
+
'tlsKeyFile': self.tls_key_file,
|
|
173
|
+
'tlsCaCertFile': self.tls_ca_cert_file,
|
|
174
|
+
'tlsPassphrase': self.tls_passphrase,
|
|
175
|
+
'password': self.oss_password,
|
|
176
|
+
'terminateRetries': self.terminate_retries,
|
|
177
|
+
'terminateRetrySecs': self.terminate_retry_secs,
|
|
178
|
+
'redisConfigFile': self.redis_config_file,
|
|
179
|
+
}
|
|
180
|
+
return kwargs
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class Env:
|
|
184
|
+
RTestInstance = None
|
|
185
|
+
EnvCompareParams = ['module', 'moduleArgs', 'env', 'useSlaves', 'shardsCount', 'useAof',
|
|
186
|
+
'useRdbPreamble', 'forceTcp', 'enableDebugCommand', 'enableProtectedConfigs',
|
|
187
|
+
'enableModuleCommand', 'protocol', 'password']
|
|
188
|
+
|
|
189
|
+
def compareEnvs(self, env):
|
|
190
|
+
if env is None:
|
|
191
|
+
return False
|
|
192
|
+
for param in Env.EnvCompareParams:
|
|
193
|
+
if self.__dict__[param] != env.__dict__[param]:
|
|
194
|
+
return False
|
|
195
|
+
return True
|
|
196
|
+
|
|
197
|
+
def __init__(self, testName=None, testDescription=None, module=None,
|
|
198
|
+
moduleArgs=None, env=None, useSlaves=None, shardsCount=None, decodeResponses=None, password=None,
|
|
199
|
+
useAof=None, useRdbPreamble=None, forceTcp=False, useTLS=False, tlsCertFile=None, tlsKeyFile=None,
|
|
200
|
+
tlsCaCertFile=None, tlsPassphrase=None, logDir=None, redisBinaryPath=None, dmcBinaryPath=None,
|
|
201
|
+
redisEnterpriseBinaryPath=None, noDefaultModuleArgs=False, clusterNodeTimeout = None,
|
|
202
|
+
freshEnv=False, enableDebugCommand=None, enableModuleCommand=None, enableProtectedConfigs=None, protocol=None,
|
|
203
|
+
terminateRetries=None, terminateRetrySecs=None, redisConfigFile=None):
|
|
204
|
+
|
|
205
|
+
self.testName = testName if testName else Defaults.curr_test_name
|
|
206
|
+
if self.testName is None:
|
|
207
|
+
self.testName = '%s.%s' % (inspect.getmodule(inspect.currentframe().f_back).__name__, inspect.currentframe().f_back.f_code.co_name)
|
|
208
|
+
self.testName = self.testName.replace(' ', '_')
|
|
209
|
+
|
|
210
|
+
if testDescription:
|
|
211
|
+
print(Colors.Gray('\tdescription: ' + testDescription))
|
|
212
|
+
|
|
213
|
+
self.module = fix_modules(module, Defaults.module)
|
|
214
|
+
if noDefaultModuleArgs:
|
|
215
|
+
self.moduleArgs = fix_modulesArgs(self.module, moduleArgs)
|
|
216
|
+
else:
|
|
217
|
+
self.moduleArgs = fix_modulesArgs(self.module, moduleArgs, Defaults.module_args)
|
|
218
|
+
self.env = env if env else Defaults.env
|
|
219
|
+
self.useSlaves = useSlaves if useSlaves else Defaults.use_slaves
|
|
220
|
+
self.shardsCount = shardsCount if shardsCount else Defaults.num_shards
|
|
221
|
+
self.decodeResponses = decodeResponses if decodeResponses else Defaults.decode_responses
|
|
222
|
+
self.useAof = useAof if useAof else Defaults.use_aof
|
|
223
|
+
self.useRdbPreamble = useRdbPreamble if useRdbPreamble is not None else Defaults.use_rdb_preamble
|
|
224
|
+
self.verbose = Defaults.verbose
|
|
225
|
+
self.logDir = logDir if logDir else Defaults.logdir
|
|
226
|
+
self.forceTcp = forceTcp
|
|
227
|
+
self.password = password
|
|
228
|
+
self.debugger = Defaults.debugger
|
|
229
|
+
self.sanitizer = Defaults.sanitizer
|
|
230
|
+
self.useTLS = useTLS if useTLS else Defaults.use_TLS
|
|
231
|
+
self.tlsCertFile = tlsCertFile if tlsCertFile else Defaults.tls_cert_file
|
|
232
|
+
self.tlsKeyFile = tlsKeyFile if tlsKeyFile else Defaults.tls_key_file
|
|
233
|
+
self.tlsCaCertFile = tlsCaCertFile if tlsCaCertFile else Defaults.tls_ca_cert_file
|
|
234
|
+
self.tlsPassphrase = tlsPassphrase if tlsPassphrase else Defaults.tls_passphrase
|
|
235
|
+
|
|
236
|
+
self.redisBinaryPath = expandBinary(redisBinaryPath) if redisBinaryPath else Defaults.binary
|
|
237
|
+
self.dmcBinaryPath = expandBinary(dmcBinaryPath) if dmcBinaryPath else Defaults.proxy_binary
|
|
238
|
+
self.redisEnterpriseBinaryPath = expandBinary(redisEnterpriseBinaryPath) if redisEnterpriseBinaryPath else Defaults.re_binary
|
|
239
|
+
self.clusterNodeTimeout = clusterNodeTimeout if clusterNodeTimeout else Defaults.cluster_node_timeout
|
|
240
|
+
self.port = Defaults.port
|
|
241
|
+
self.enableDebugCommand = enableDebugCommand if enableDebugCommand is not None else Defaults.enable_debug_command
|
|
242
|
+
self.enableProtectedConfigs = enableProtectedConfigs if enableProtectedConfigs is not None\
|
|
243
|
+
else Defaults.enable_protected_configs
|
|
244
|
+
self.enableModuleCommand = enableModuleCommand if enableModuleCommand is not None else Defaults.enable_module_command
|
|
245
|
+
|
|
246
|
+
self.terminateRetries = terminateRetries
|
|
247
|
+
self.terminateRetrySecs = terminateRetrySecs
|
|
248
|
+
|
|
249
|
+
self.protocol = protocol if protocol is not None else Defaults.protocol
|
|
250
|
+
|
|
251
|
+
self.redisConfigFile = redisConfigFile if redisConfigFile is not None else Defaults.redis_config_file
|
|
252
|
+
|
|
253
|
+
self.assertionFailedSummary = []
|
|
254
|
+
|
|
255
|
+
if not freshEnv and Env.RTestInstance and Env.RTestInstance.currEnv and self.compareEnvs(Env.RTestInstance.currEnv):
|
|
256
|
+
self.envRunner = Env.RTestInstance.currEnv.envRunner
|
|
257
|
+
else:
|
|
258
|
+
if Env.RTestInstance and Env.RTestInstance.currEnv:
|
|
259
|
+
Env.RTestInstance.currEnv.stop()
|
|
260
|
+
self.envRunner = self.getEnvByName()
|
|
261
|
+
|
|
262
|
+
try:
|
|
263
|
+
os.makedirs(self.logDir)
|
|
264
|
+
except Exception:
|
|
265
|
+
pass
|
|
266
|
+
|
|
267
|
+
self.start()
|
|
268
|
+
if self.verbose >= 2:
|
|
269
|
+
print(Colors.Blue('\tenv data:'))
|
|
270
|
+
self.envRunner.printEnvData('\t\t')
|
|
271
|
+
|
|
272
|
+
if Env.RTestInstance:
|
|
273
|
+
Env.RTestInstance.currEnv = self
|
|
274
|
+
|
|
275
|
+
if Defaults.debug_pause:
|
|
276
|
+
input('\tenv is up, attach to any process with gdb and press any button to continue.')
|
|
277
|
+
|
|
278
|
+
def getInformationBeforeDispose(self):
|
|
279
|
+
return {
|
|
280
|
+
"env": self.env,
|
|
281
|
+
"test": self.testName,
|
|
282
|
+
"env_info": self.envRunner.getInformationBeforeDispose()
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
def getInformationAfterDispose(self):
|
|
286
|
+
return self.envRunner.getInformationAfterDispose()
|
|
287
|
+
|
|
288
|
+
def getEnvByName(self):
|
|
289
|
+
verbose = False
|
|
290
|
+
kwargs = self.getEnvKwargs()
|
|
291
|
+
single_args = self.getSingleArgs()
|
|
292
|
+
|
|
293
|
+
test_fname = self.testName.replace(':', '_')
|
|
294
|
+
|
|
295
|
+
if self.env == 'oss':
|
|
296
|
+
kwargs.update(single_args)
|
|
297
|
+
kwargs['password'] = Defaults.oss_password if self.password is None else self.password
|
|
298
|
+
return StandardEnv(redisBinaryPath=self.redisBinaryPath,
|
|
299
|
+
outputFilesFormat='%s-' + '%s-oss' % test_fname,
|
|
300
|
+
**kwargs)
|
|
301
|
+
if self.env == 'enterprise':
|
|
302
|
+
kwargs.update(single_args)
|
|
303
|
+
kwargs['libPath'] = Defaults.re_libdir
|
|
304
|
+
return StandardEnv(redisBinaryPath=self.redisEnterpriseBinaryPath,
|
|
305
|
+
outputFilesFormat='%s-' + '%s-oss' % test_fname,
|
|
306
|
+
**kwargs)
|
|
307
|
+
if self.env == 'enterprise-cluster':
|
|
308
|
+
kwargs['libPath'] = Defaults.re_libdir
|
|
309
|
+
return EnterpriseClusterEnv(shardsCount=self.shardsCount,
|
|
310
|
+
redisBinaryPath=self.redisEnterpriseBinaryPath,
|
|
311
|
+
outputFilesFormat='%s-' + '%s-re-cluster' % test_fname,
|
|
312
|
+
dmcBinaryPath=Defaults.proxy_binary,
|
|
313
|
+
**kwargs)
|
|
314
|
+
if self.env == 'oss-cluster':
|
|
315
|
+
kwargs['password'] = Defaults.oss_password if self.password is None else self.password
|
|
316
|
+
return ClusterEnv(shardsCount=self.shardsCount, redisBinaryPath=self.redisBinaryPath,
|
|
317
|
+
outputFilesFormat='%s-' + '%s-oss-cluster' % test_fname,
|
|
318
|
+
randomizePorts=Defaults.randomize_ports,
|
|
319
|
+
**kwargs)
|
|
320
|
+
|
|
321
|
+
if self.env == 'existing-env':
|
|
322
|
+
return ExistsRedisEnv(addr=Defaults.external_addr, **kwargs)
|
|
323
|
+
|
|
324
|
+
if self.env == 'cluster_existing-env':
|
|
325
|
+
return EnterpriseRedisClusterEnv(addr = Defaults.external_addr, password = Defaults.internal_password,
|
|
326
|
+
shards_port=Defaults.shards_ports,
|
|
327
|
+
cluster_address = Defaults.cluster_address,
|
|
328
|
+
cluster_credentials= Defaults.cluster_credentials, **kwargs)
|
|
329
|
+
|
|
330
|
+
def getSingleArgs(self):
|
|
331
|
+
single_args = {}
|
|
332
|
+
if Defaults.randomize_ports:
|
|
333
|
+
single_args['port'] = 0
|
|
334
|
+
if Defaults.use_unix:
|
|
335
|
+
single_args['unix'] = True
|
|
336
|
+
if self.forceTcp and self.env != 'existing-env':
|
|
337
|
+
single_args['port'] = 0
|
|
338
|
+
single_args.pop('unix', None)
|
|
339
|
+
return single_args
|
|
340
|
+
|
|
341
|
+
def getEnvKwargs(self):
|
|
342
|
+
kwargs = {
|
|
343
|
+
'modulePath': self.module,
|
|
344
|
+
'moduleArgs': self.moduleArgs,
|
|
345
|
+
'useSlaves': self.useSlaves,
|
|
346
|
+
'decodeResponses': self.decodeResponses,
|
|
347
|
+
'useAof': self.useAof,
|
|
348
|
+
'useRdbPreamble': self.useRdbPreamble,
|
|
349
|
+
'dbDirPath': self.logDir,
|
|
350
|
+
'loglevel': Defaults.loglevel,
|
|
351
|
+
'debugger': Defaults.debugger,
|
|
352
|
+
'sanitizer': Defaults.sanitizer,
|
|
353
|
+
'noCatch': Defaults.no_capture_output,
|
|
354
|
+
'noLog': Defaults.no_log,
|
|
355
|
+
'verbose': Defaults.verbose,
|
|
356
|
+
'useTLS': self.useTLS,
|
|
357
|
+
'tlsCertFile': self.tlsCertFile,
|
|
358
|
+
'tlsKeyFile': self.tlsKeyFile,
|
|
359
|
+
'tlsCaCertFile': self.tlsCaCertFile,
|
|
360
|
+
'clusterNodeTimeout': self.clusterNodeTimeout,
|
|
361
|
+
'tlsPassphrase': self.tlsPassphrase,
|
|
362
|
+
'port': self.port,
|
|
363
|
+
'enableDebugCommand': self.enableDebugCommand,
|
|
364
|
+
'enableProtectedConfigs': self.enableProtectedConfigs,
|
|
365
|
+
'enableModuleCommand': self.enableModuleCommand,
|
|
366
|
+
'protocol': self.protocol,
|
|
367
|
+
'terminateRetries': self.terminateRetries,
|
|
368
|
+
'terminateRetrySecs': self.terminateRetrySecs,
|
|
369
|
+
'redisConfigFile': self.redisConfigFile,
|
|
370
|
+
}
|
|
371
|
+
return kwargs
|
|
372
|
+
|
|
373
|
+
def start(self, masters = True, slaves = True ):
|
|
374
|
+
self.envRunner.startEnv(masters, slaves)
|
|
375
|
+
self.con = self.getConnection()
|
|
376
|
+
|
|
377
|
+
def stop(self, masters = True, slaves = True):
|
|
378
|
+
self.envRunner.stopEnv(masters, slaves)
|
|
379
|
+
|
|
380
|
+
def stopEnvWithSegFault(self, masters = True, slaves = True):
|
|
381
|
+
self.envRunner.stopEnvWithSegFault(masters, slaves)
|
|
382
|
+
|
|
383
|
+
def getEnvStr(self):
|
|
384
|
+
return self.env
|
|
385
|
+
|
|
386
|
+
def getConnection(self, shardId=1):
|
|
387
|
+
return self.envRunner.getConnection(shardId)
|
|
388
|
+
|
|
389
|
+
def getClusterConnectionIfNeeded(self):
|
|
390
|
+
if isinstance(self.envRunner, ClusterEnv):
|
|
391
|
+
return self.envRunner.getClusterConnection()
|
|
392
|
+
elif isinstance(self.envRunner, EnterpriseRedisClusterEnv):
|
|
393
|
+
return self.envRunner.getClusterConnection()
|
|
394
|
+
else:
|
|
395
|
+
return self.getConnection()
|
|
396
|
+
|
|
397
|
+
def addShardToClusterIfExists(self):
|
|
398
|
+
if isinstance(self.envRunner, ClusterEnv):
|
|
399
|
+
test_fname = self.testName.replace(':', '_')
|
|
400
|
+
output_files_format = '%s-' + '%s-oss-cluster' % test_fname
|
|
401
|
+
kwargs = self.getEnvKwargs()
|
|
402
|
+
return self.envRunner.addShardToCluster(self.redisBinaryPath, output_files_format, **kwargs)
|
|
403
|
+
else:
|
|
404
|
+
raise Exception("env is not an oss-cluster")
|
|
405
|
+
|
|
406
|
+
def getSlaveConnection(self):
|
|
407
|
+
return self.envRunner.getSlaveConnection()
|
|
408
|
+
|
|
409
|
+
# List of nodes that initial bootstrapping can be done from
|
|
410
|
+
def getMasterNodesList(self):
|
|
411
|
+
return self.envRunner.getMasterNodesList()
|
|
412
|
+
|
|
413
|
+
# List containing a connection for each of the master nodes
|
|
414
|
+
def getOSSMasterNodesConnectionList(self):
|
|
415
|
+
return self.envRunner.getOSSMasterNodesConnectionList()
|
|
416
|
+
|
|
417
|
+
def getConnectionByKey(self, key, command):
|
|
418
|
+
return self.envRunner.getConnectionByKey(key, command)
|
|
419
|
+
|
|
420
|
+
def flush(self):
|
|
421
|
+
self.envRunner.flush()
|
|
422
|
+
|
|
423
|
+
def isCluster(self):
|
|
424
|
+
return 'cluster' in self.env or os.getenv("RLEC_CLUSTER") == "1"
|
|
425
|
+
|
|
426
|
+
def isEnterpiseCluster(self):
|
|
427
|
+
return isinstance(self.envRunner, EnterpriseRedisClusterEnv)
|
|
428
|
+
|
|
429
|
+
def isDebugger(self):
|
|
430
|
+
return self.debugger is not None
|
|
431
|
+
|
|
432
|
+
def _getCallerPosition(self, back_frames):
|
|
433
|
+
frame = inspect.currentframe()
|
|
434
|
+
while frame and back_frames > 0:
|
|
435
|
+
back_frames -= 1
|
|
436
|
+
frame = frame.f_back
|
|
437
|
+
if frame:
|
|
438
|
+
return '%s:%s' % (
|
|
439
|
+
os.path.basename(frame.f_code.co_filename),
|
|
440
|
+
frame.f_lineno)
|
|
441
|
+
|
|
442
|
+
def _assertion(self, checkStr, trueValue, depth=0, message=None):
|
|
443
|
+
basemsg = Colors.Yellow(checkStr) + '\t' + Colors.Gray(self._getCallerPosition(3 + depth))
|
|
444
|
+
if message:
|
|
445
|
+
basemsg += ' [{}]'.format(message)
|
|
446
|
+
|
|
447
|
+
if trueValue and self.verbose:
|
|
448
|
+
print('\t' + Colors.Green('✅ (OK):\t') + basemsg)
|
|
449
|
+
elif not trueValue:
|
|
450
|
+
failureSummary = Colors.Bred('❌ (FAIL):\t') + basemsg
|
|
451
|
+
print('\t' + failureSummary)
|
|
452
|
+
if Defaults.exit_on_failure:
|
|
453
|
+
raise TestAssertionFailure('Assertion Failed!')
|
|
454
|
+
|
|
455
|
+
self.assertionFailedSummary.append(failureSummary)
|
|
456
|
+
|
|
457
|
+
def getNumberOfFailedAssertion(self):
|
|
458
|
+
return len(self.assertionFailedSummary)
|
|
459
|
+
|
|
460
|
+
def assertEqual(self, first, second, depth=0, message=None):
|
|
461
|
+
self._assertion('%s == %s' % (repr(first), repr(second)), first == second, depth, message=message)
|
|
462
|
+
|
|
463
|
+
def assertNotEqual(self, first, second, depth=0, message=None):
|
|
464
|
+
self._assertion('%s != %s' % (repr(first), repr(second)), first != second, depth, message=message)
|
|
465
|
+
|
|
466
|
+
def assertOk(self, val, depth=0, message=None):
|
|
467
|
+
self.assertEqual(val, 'OK', depth + 1, message=message)
|
|
468
|
+
|
|
469
|
+
def assertTrue(self, val, depth=0, message=None):
|
|
470
|
+
self.assertEqual(bool(val), True, depth + 1, message=message)
|
|
471
|
+
|
|
472
|
+
def assertFalse(self, val, depth=0, message=None):
|
|
473
|
+
self.assertEqual(bool(val), False, depth + 1, message=message)
|
|
474
|
+
|
|
475
|
+
def assertContains(self, value, holder, depth=0, message=None):
|
|
476
|
+
self._assertion('%s should contain %s' % (repr(holder), repr(value)), value in holder, depth, message=message)
|
|
477
|
+
|
|
478
|
+
def assertNotContains(self, value, holder, depth=0, message=None):
|
|
479
|
+
self._assertion('%s should not contain %s' % (repr(holder), repr(value)), value not in holder, depth, message=message)
|
|
480
|
+
|
|
481
|
+
def assertGreaterEqual(self, value1, value2, depth=0, message=None):
|
|
482
|
+
self._assertion('%s >= %s' % (repr(value1), repr(value2)), value1 >= value2, depth, message=message)
|
|
483
|
+
|
|
484
|
+
def assertGreater(self, value1, value2, depth=0, message=None):
|
|
485
|
+
self._assertion('%s > %s' % (repr(value1), repr(value2)), value1 > value2, depth, message=message)
|
|
486
|
+
|
|
487
|
+
def assertLessEqual(self, value1, value2, depth=0, message=None):
|
|
488
|
+
self._assertion('%s <= %s' % (repr(value1), repr(value2)), value1 <= value2, depth, message=message)
|
|
489
|
+
|
|
490
|
+
def assertLess(self, value1, value2, depth=0, message=None):
|
|
491
|
+
self._assertion('%s < %s' % (repr(value1), repr(value2)), value1 < value2, depth, message=message)
|
|
492
|
+
|
|
493
|
+
def assertIsNotNone(self, value, depth=0, message=None):
|
|
494
|
+
self._assertion('%s is not None' % (repr(value)), value is not None, depth, message=message)
|
|
495
|
+
|
|
496
|
+
def assertIsNone(self, value, depth=0, message=None):
|
|
497
|
+
self._assertion('%s is None' % (repr(value)), value is None, depth, message=message)
|
|
498
|
+
|
|
499
|
+
def assertIsInstance(self, value, instance, depth=0, message=None):
|
|
500
|
+
self._assertion('%s instance of %s' % (repr(value), repr(instance)), isinstance(value, instance), depth, message=message)
|
|
501
|
+
|
|
502
|
+
def assertAlmostEqual(self, value1, value2, delta, depth=0, message=None):
|
|
503
|
+
self._assertion('%s almost equels %s (delta %s)' % (repr(value1), repr(value2), repr(delta)), abs(value1 - value2) <= delta, depth, message)
|
|
504
|
+
|
|
505
|
+
def expect(self, *query, **options):
|
|
506
|
+
return Query(self, *query, **options)
|
|
507
|
+
|
|
508
|
+
def cmd(self, *query, **options):
|
|
509
|
+
res = self.con.execute_command(*query, **options)
|
|
510
|
+
self.debugPrint('query: %s, result: %s' % (repr(query), repr(res)))
|
|
511
|
+
return res
|
|
512
|
+
|
|
513
|
+
def assertCmdOk(self, cmd, *args, **kwargs):
|
|
514
|
+
self.assertOk(self.cmd(cmd, *args, **kwargs))
|
|
515
|
+
|
|
516
|
+
def exists(self, val):
|
|
517
|
+
warnings.warn("Exists is deprecated, use cmd instead", DeprecationWarning)
|
|
518
|
+
return self.envRunner.exists(val)
|
|
519
|
+
|
|
520
|
+
def assertExists(self, val, depth=0):
|
|
521
|
+
warnings.warn("AssertExists is deprecated, use cmd instead", DeprecationWarning)
|
|
522
|
+
self._assertion('%s exists in db' % repr(val), self.con.exists(val), depth=0)
|
|
523
|
+
|
|
524
|
+
def executeCommand(self, *query, **options):
|
|
525
|
+
warnings.warn("execute_command is deprecated, use cmd instead", DeprecationWarning)
|
|
526
|
+
return self.cmd(*query, **options)
|
|
527
|
+
|
|
528
|
+
def reloadingIterator(self):
|
|
529
|
+
yield 1
|
|
530
|
+
self.dumpAndReload()
|
|
531
|
+
yield 2
|
|
532
|
+
|
|
533
|
+
def dumpAndReload(self, restart=False, shardId=None, timeout_sec=40):
|
|
534
|
+
self.envRunner.dumpAndReload(restart=restart, shardId=shardId, timeout_sec=timeout_sec)
|
|
535
|
+
|
|
536
|
+
def hmset(self, *args):
|
|
537
|
+
warnings.warn("hmset is deprecated, use Cmd instead", DeprecationWarning)
|
|
538
|
+
return self.envRunner.hmset(*args)
|
|
539
|
+
|
|
540
|
+
def keys(self, reg):
|
|
541
|
+
warnings.warn("keys is deprecated, use Cmd instead", DeprecationWarning)
|
|
542
|
+
return self.envRunner.keys(reg)
|
|
543
|
+
|
|
544
|
+
def assertRaises(self, var1, var2, *query):
|
|
545
|
+
warnings.warn("assertRaises is deprecated, use Expect + RaiseError instead", DeprecationWarning)
|
|
546
|
+
self.expect(*query).raiseError()
|
|
547
|
+
|
|
548
|
+
@contextlib.contextmanager
|
|
549
|
+
def assertResponseError(self, msg=None, contained=None):
|
|
550
|
+
"""
|
|
551
|
+
Assert that a context block with a redis command triggers a redis error response.
|
|
552
|
+
|
|
553
|
+
For Example:
|
|
554
|
+
|
|
555
|
+
with self.assertResponseError():
|
|
556
|
+
r.execute_command('non_existing_command')
|
|
557
|
+
"""
|
|
558
|
+
|
|
559
|
+
warnings.warn("assertResponseError is deprecated, use Expect + RaiseError instead", DeprecationWarning)
|
|
560
|
+
|
|
561
|
+
try:
|
|
562
|
+
yield 1
|
|
563
|
+
except Exception as e:
|
|
564
|
+
if contained:
|
|
565
|
+
self.assertContains(contained, str(e), depth=2)
|
|
566
|
+
self._assertion('Expected Response Error', True, depth=1)
|
|
567
|
+
else:
|
|
568
|
+
self._assertion('Expected Response Error', False, depth=1)
|
|
569
|
+
|
|
570
|
+
def restartAndReload(self, shardId=None, timeout_sec=40):
|
|
571
|
+
self.dumpAndReload(restart=True, shardId=shardId, timeout_sec=timeout_sec)
|
|
572
|
+
|
|
573
|
+
def broadcast(self, *cmd):
|
|
574
|
+
self.envRunner.broadcast(*cmd)
|
|
575
|
+
|
|
576
|
+
def debugPrint(self, msg, force=False):
|
|
577
|
+
if Defaults.debug_print or force:
|
|
578
|
+
print('\t' + Colors.Bold('debug:\t') + Colors.Gray(msg))
|
|
579
|
+
|
|
580
|
+
def checkExitCode(self):
|
|
581
|
+
return self.envRunner.checkExitCode()
|
|
582
|
+
|
|
583
|
+
def isUp(self):
|
|
584
|
+
return self.envRunner.isUp()
|
|
585
|
+
|
|
586
|
+
def isHealthy(self):
|
|
587
|
+
return self.envRunner.isHealthy()
|
|
588
|
+
|
|
589
|
+
def skip(self):
|
|
590
|
+
raise unittest.SkipTest()
|
|
591
|
+
|
|
592
|
+
def skipOnDebugger(self):
|
|
593
|
+
if self.isDebugger():
|
|
594
|
+
self.skip()
|
|
595
|
+
|
|
596
|
+
def skipOnCluster(self):
|
|
597
|
+
if self.isCluster():
|
|
598
|
+
self.skip()
|
|
599
|
+
|
|
600
|
+
def skipOnAOF(self):
|
|
601
|
+
if self.useAof:
|
|
602
|
+
self.skip()
|
|
603
|
+
|
|
604
|
+
def skipOnSlave(self):
|
|
605
|
+
if self.useSlaves:
|
|
606
|
+
self.skip()
|
|
607
|
+
|
|
608
|
+
def skipOnVersionSmaller(self, _version):
|
|
609
|
+
res = self.con.execute_command('INFO')
|
|
610
|
+
if(version.parse(res['redis_version']) < version.parse(_version)):
|
|
611
|
+
self.skip() # copy exists only from version 6
|
|
612
|
+
|
|
613
|
+
def isUnixSocket(self):
|
|
614
|
+
return self.envRunner.isUnixSocket()
|
|
615
|
+
|
|
616
|
+
def isTcp(self):
|
|
617
|
+
return self.envRunner.isTcp()
|
|
618
|
+
|
|
619
|
+
def skipOnTcp(self):
|
|
620
|
+
if self.isTcp():
|
|
621
|
+
self.skip()
|
|
622
|
+
|
|
623
|
+
def skipOnUnixSocket(self):
|
|
624
|
+
if self.isUnixSocket():
|
|
625
|
+
self.skip()
|
|
626
|
+
|
|
627
|
+
def skipOnEnterpriseCluster(self):
|
|
628
|
+
if self.isEnterpiseCluster():
|
|
629
|
+
self.skip()
|
|
630
|
+
|
|
631
|
+
_mm = {
|
|
632
|
+
'assertEquals': assertEqual,
|
|
633
|
+
'assertListEqual': assertEqual,
|
|
634
|
+
'retry_with_reload': reloadingIterator,
|
|
635
|
+
'retry_with_rdb_reload': reloadingIterator,
|
|
636
|
+
'reloading_iterator': reloadingIterator,
|
|
637
|
+
'dump_and_reload': dumpAndReload,
|
|
638
|
+
'restart_and_reload': restartAndReload,
|
|
639
|
+
'execute_command': cmd,
|
|
640
|
+
'assertIn': assertContains,
|
|
641
|
+
'assertNotIn': assertNotContains,
|
|
642
|
+
'is_cluster': isCluster,
|
|
643
|
+
'is_enterprise_redis_clusterEnv':isEnterpiseCluster
|
|
644
|
+
}
|
|
645
|
+
for k, v in _mm.items():
|
|
646
|
+
locals().update({k:genDeprecated(k, v)})
|