main
py 102 lines 2.48 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import asyncio
4 import tempfile
5 from pathlib import Path
6 from ssl import SSLContext
7
8 import pytest
9
10 from vllm.entrypoints.launchers.utils.ssl import SSLCertRefresher
11
12
13 class MockSSLContext(SSLContext):
14 def __init__(self):
15 self.load_cert_chain_count = 0
16 self.load_ca_count = 0
17
18 def load_cert_chain(
19 self,
20 certfile,
21 keyfile=None,
22 password=None,
23 ):
24 self.load_cert_chain_count += 1
25
26 def load_verify_locations(
27 self,
28 cafile=None,
29 capath=None,
30 cadata=None,
31 ):
32 self.load_ca_count += 1
33
34
35 def create_file() -> str:
36 with tempfile.NamedTemporaryFile(dir="/tmp", delete=False) as f:
37 return f.name
38
39
40 def touch_file(path: str) -> None:
41 Path(path).touch()
42
43
44 async def wait_for_counts(
45 ssl_context: MockSSLContext,
46 *,
47 cert_chain_count: int,
48 ca_count: int,
49 timeout: float = 5.0,
50 ) -> None:
51 deadline = asyncio.get_running_loop().time() + timeout
52 while True:
53 if (
54 ssl_context.load_cert_chain_count >= cert_chain_count
55 and ssl_context.load_ca_count >= ca_count
56 ):
57 return
58
59 if asyncio.get_running_loop().time() >= deadline:
60 assert ssl_context.load_cert_chain_count >= cert_chain_count
61 assert ssl_context.load_ca_count >= ca_count
62
63 await asyncio.sleep(0.05)
64
65
66 @pytest.mark.asyncio
67 async def test_ssl_refresher():
68 ssl_context = MockSSLContext()
69 key_path = create_file()
70 cert_path = create_file()
71 ca_path = create_file()
72 ssl_refresher = SSLCertRefresher(ssl_context, key_path, cert_path, ca_path)
73 await asyncio.sleep(1)
74 assert ssl_context.load_cert_chain_count == 0
75 assert ssl_context.load_ca_count == 0
76
77 touch_file(key_path)
78 await wait_for_counts(
79 ssl_context,
80 cert_chain_count=1,
81 ca_count=0,
82 )
83 assert ssl_context.load_ca_count == 0
84
85 touch_file(cert_path)
86 touch_file(ca_path)
87 await wait_for_counts(
88 ssl_context,
89 cert_chain_count=2,
90 ca_count=1,
91 )
92
93 ssl_refresher.stop()
94 await asyncio.sleep(0)
95 cert_chain_count = ssl_context.load_cert_chain_count
96 ca_count = ssl_context.load_ca_count
97
98 touch_file(cert_path)
99 touch_file(ca_path)
100 await asyncio.sleep(1)
101 assert ssl_context.load_cert_chain_count == cert_chain_count
102 assert ssl_context.load_ca_count == ca_count