Skip to content

Commit 57ce589

Browse files
Adapt Tests to Allow External Server Connections (#7)
* Adding files Signed-off-by: Nikhil Manglore <[email protected]> * Adding conftest Signed-off-by: Nikhil Manglore <[email protected]> * Final commits Signed-off-by: Nikhil Manglore <[email protected]> * Adding framework Signed-off-by: Nikhil Manglore <[email protected]> * Finaly additions Signed-off-by: Nikhil Manglore <[email protected]> * Added methods to allow bloom handling Signed-off-by: Nikhil Manglore <[email protected]> * Fixed formatting Signed-off-by: Nikhil Manglore <[email protected]> * Added new base class Signed-off-by: Nikhil Manglore <[email protected]> * Optimizations Signed-off-by: Nikhil Manglore <[email protected]> * Minor formatting changes Signed-off-by: Nikhil Manglore <[email protected]> * Addressed suggestions Signed-off-by: Nikhil Manglore <[email protected]> * Minor Change Signed-off-by: Nikhil Manglore <[email protected]> * Running rdb tests now Signed-off-by: Nikhil Manglore <[email protected]> * Fixed formatting Signed-off-by: Nikhil Manglore <[email protected]> * Removed client stuff Signed-off-by: Nikhil Manglore <[email protected]> * moved docker commands out of valkey-test-framework Signed-off-by: Nikhil Manglore <[email protected]> * Fixed formatting Signed-off-by: Nikhil Manglore <[email protected]> * Minor changes Signed-off-by: Nikhil Manglore <[email protected]> * Addressed comments Signed-off-by: Nikhil Manglore <[email protected]> --------- Signed-off-by: Nikhil Manglore <[email protected]> Signed-off-by: Nikhil Manglore <[email protected]>
1 parent b84b016 commit 57ce589

File tree

2 files changed

+129
-17
lines changed

2 files changed

+129
-17
lines changed

src/valkey_test_case.py

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,17 @@ class ValkeyServerHandle(object):
6767
DEFAULT_BIND_IP = "0.0.0.0"
6868

6969
def __init__(
70-
self, bind_ip, port, port_tracker, server_path="valkey-server", cwd="."
70+
self,
71+
bind_ip,
72+
port,
73+
port_tracker,
74+
server_path="valkey-server",
75+
cwd=".",
76+
external_mode=False,
7177
):
7278
self.server = None
7379
self.client = None
80+
self.external_mode = external_mode
7481
self.port = port
7582
self.bind_ip = bind_ip
7683
self.args = {}
@@ -82,27 +89,31 @@ def __init__(
8289
self.valkey_path = server_path
8390
self.conf_file = None
8491

85-
@classmethod
86-
def create_from_server(self, server, db=0):
87-
logging.info(("Created regular client for port {}".format(server.port)))
88-
r = StrictValkey(host=server.bind_ip, port=server.port, db=db)
92+
def create_from_server(self, db=0):
93+
logging.info(("Created regular client for port {}".format(self.port)))
94+
r = StrictValkey(host=self.bind_ip, port=self.port, db=db)
8995
return r
9096

9197
def set_startup_args(self, args):
9298
self.args.update(args)
9399

94100
def get_new_client(self):
95-
return self.create_from_server(self)
101+
return self.create_from_server()
96102

97103
def exit(self, cleanup=True, remove_nodes_conf=True):
98104
if self.client:
99-
try:
100-
self.client.shutdown("nosave")
101-
except:
102-
logging.warning("SHUTDOWN was unsuccessful")
103-
105+
if not self.external_mode:
106+
try:
107+
self.client.shutdown("nosave")
108+
except:
109+
logging.warning("SHUTDOWN was unsuccessful")
110+
self.client.close()
104111
self.client = None
105112

113+
# No server process to clean up if we're using an external server
114+
if self.external_mode:
115+
return
116+
106117
if self.server:
107118
self._waitForExit()
108119
self.server = None
@@ -147,7 +158,7 @@ def _waitForExit(self):
147158
logging.warning("Server did not exit in time, killing...")
148159
if self.is_alive():
149160
# check server is still running before kill it.
150-
self.kill()
161+
self.server.kill()
151162
try:
152163
self.wait_for_shutdown()
153164
except WaitTimeout:
@@ -267,8 +278,13 @@ def start(self, wait_for_ping=True, connect_client=True):
267278
return self.client
268279

269280
def restart(self, remove_rdb=True, remove_nodes_conf=True, connect_client=True):
270-
self.exit(remove_rdb, remove_nodes_conf)
271-
self.start(connect_client=connect_client)
281+
if self.external_mode:
282+
return self._test_instance.restart_external_server(
283+
self, remove_rdb, remove_nodes_conf, connect_client
284+
)
285+
else:
286+
self.exit(remove_rdb, remove_nodes_conf)
287+
self.start(connect_client=connect_client)
272288

273289
def is_alive(self):
274290
try:
@@ -293,12 +309,13 @@ def wait_for_key(self, key, value):
293309
)
294310

295311
def connect(self):
296-
c = self.create_from_server(self)
312+
c = self.create_from_server()
297313
try:
298314
self._waitForPing(c)
299315
except WaitTimeout:
300316
raise RuntimeError("Failed to connect or ping server")
301317
self.client = c
318+
return self.client
302319

303320
def wait_for_save_done(self, client=None):
304321
"""Wait for the save to complete, failing if it does not complete successfully in the timeout"""
@@ -324,8 +341,13 @@ def wait_for_save_in_progress(self, client=None):
324341
)
325342

326343
def is_rdb_done_loading(self):
327-
rdb_load_log = "Done loading RDB"
328-
return self.verify_string_in_logfile(rdb_load_log) == True
344+
if self.external_mode:
345+
info = self.client.info()
346+
return info.get("loading", 0) == 0
347+
else:
348+
# Local server logic
349+
rdb_load_log = "Done loading RDB"
350+
return self.verify_string_in_logfile(rdb_load_log) == True
329351

330352
def num_replicas_online(self, client=None):
331353
if client is None:
@@ -495,12 +517,32 @@ def create_server(
495517
args="",
496518
skip_teardown=False,
497519
conf_file=None,
520+
external_server=False,
498521
):
522+
523+
if external_server:
524+
if not bind_ip:
525+
raise ValueError("Bind ip must be specified for external server use")
526+
if not port:
527+
raise ValueError("Port must be specified for external server use")
528+
529+
valkey_server = ValkeyServerHandle(
530+
bind_ip, port, port_tracker=None, external_mode=True
531+
)
532+
533+
valkey_server._test_instance = self
534+
valkey_cli = valkey_server.connect()
535+
536+
if not skip_teardown:
537+
self.server_list.append(valkey_server)
538+
return valkey_server, valkey_cli
539+
499540
if not bind_ip:
500541
bind_ip = self.get_bind_ip()
501542

502543
if not port:
503544
port = self.get_bind_port()
545+
504546
valkey_server_handle = self.get_valkey_handle()
505547
self.server_path = server_path
506548
valkey_server = valkey_server_handle(

tests/test_external_server.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import subprocess
2+
import time
3+
from conftest import resource_port_tracker
4+
from valkey_test_case import ValkeyTestCase
5+
6+
7+
class TestExternalServer(ValkeyTestCase):
8+
"""
9+
Test for connecting to a external Valkey server
10+
"""
11+
12+
def setup_docker_server(self):
13+
container_name = "valkey-test-external"
14+
image_name = "valkey/valkey-bundle:latest"
15+
16+
pull_result = subprocess.run(
17+
["docker", "pull", image_name], capture_output=True, text=True
18+
)
19+
if pull_result.returncode != 0:
20+
raise RuntimeError(f"Failed to pull Docker image: {pull_result.stderr}")
21+
22+
subprocess.run(["docker", "stop", container_name], capture_output=True)
23+
subprocess.run(["docker", "rm", container_name], capture_output=True)
24+
25+
cmd = [
26+
"docker",
27+
"run",
28+
"-d",
29+
"-p",
30+
"6380:6379",
31+
"--name",
32+
container_name,
33+
image_name,
34+
"valkey-server",
35+
"--maxmemory",
36+
"0",
37+
"--protected-mode",
38+
"no",
39+
]
40+
41+
result = subprocess.run(cmd, capture_output=True, text=True)
42+
if result.returncode != 0:
43+
raise RuntimeError(f"Failed to start Docker container: {result.stderr}")
44+
45+
time.sleep(2)
46+
return container_name
47+
48+
def test_connect_to_external_server(self):
49+
container_name = None
50+
try:
51+
container_name = self.setup_docker_server()
52+
53+
server, client = self.create_server(
54+
testdir=self.testdir,
55+
bind_ip="localhost",
56+
port=6380,
57+
external_server=True,
58+
)
59+
60+
client.set("hello", "world")
61+
assert client.get("hello") == b"world"
62+
63+
except Exception as e:
64+
print(f"External server test failed: {e}")
65+
raise
66+
67+
finally:
68+
if container_name:
69+
subprocess.run(["docker", "stop", container_name], capture_output=True)
70+
subprocess.run(["docker", "rm", container_name], capture_output=True)

0 commit comments

Comments
 (0)