Skip to content

Commit d3d7c9a

Browse files
committed
[build] declare kvcm_ops wheel runtime dependency
1 parent 0578853 commit d3d7c9a

8 files changed

Lines changed: 161 additions & 6 deletions

File tree

.github/workflows/test-opensrc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
matrix:
3333
include:
3434
- name: normal_test
35-
test_target: "//kv_cache_manager/... //integration_test/..."
35+
test_target: "//kv_cache_manager/... //integration_test/... //package/kvcm_ops/..."
3636
test_args: ""
3737
- name: asan_test
3838
test_target: "//kv_cache_manager/... //integration_test/..."

open_source/deps/BUILD

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ load("@rules_python//python:packaging.bzl", "py_package")
44
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
55
load(":pip.bzl", "PIP_EXTRA_ARGS")
66

7-
exports_files(["requirements_base.txt"])
7+
exports_files([
8+
"requirements_base.txt",
9+
"requirements_kvcm_ops.txt",
10+
])
811

912
py_package(
1013
name = "extension_package",
@@ -24,7 +27,10 @@ compile_pip_requirements(
2427
name = "requirements_cpu",
2528
src = "requirements_cpu.txt",
2629
extra_args = PIP_EXTRA_ARGS,
27-
extra_data = ["//open_source/deps:requirements_base.txt"],
30+
extra_data = [
31+
"//open_source/deps:requirements_base.txt",
32+
"//open_source/deps:requirements_kvcm_ops.txt",
33+
],
2834
requirements_txt = "requirements_lock_cpu.txt",
2935
tags = ["manual"],
30-
)
36+
)

open_source/deps/requirements_base.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ setuptools==60.5.0
22
grpcio==1.62.0
33
grpcio-tools==1.62.0
44
protobuf==4.25
5-
requests==2.32.5
5+
-r ./requirements_kvcm_ops.txt
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
requests==2.32.5

open_source/deps/requirements_lock_cpu.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ protobuf==4.25.0 \
261261
requests==2.32.5 \
262262
--hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \
263263
--hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf
264-
# via -r open_source/deps/./requirements_base.txt
264+
# via -r open_source/deps/././requirements_kvcm_ops.txt
265265
urllib3==2.5.0 \
266266
--hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \
267267
--hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc

package/kvcm_ops/BUILD

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,36 @@ py_wheel(
1919
name = "kvcm_ops_wheel",
2020
distribution = "kvcm_ops",
2121
python_tag = "py3",
22+
requires_file = "//open_source/deps:requirements_kvcm_ops.txt",
2223
strip_path_prefixes = ["package"],
2324
version = "0.1.0",
2425
deps = [":kvcm_ops_lib"],
2526
)
2627

28+
py_test(
29+
name = "wheel_metadata_test",
30+
size = "small",
31+
srcs = ["test/wheel_metadata_test.py"],
32+
args = [
33+
"$(location :kvcm_ops_wheel)",
34+
"$(location //open_source/deps:requirements_kvcm_ops.txt)",
35+
],
36+
data = [
37+
":kvcm_ops_wheel",
38+
"//open_source/deps:requirements_kvcm_ops.txt",
39+
],
40+
main = "test/wheel_metadata_test.py",
41+
)
42+
43+
py_test(
44+
name = "wheel_install_test",
45+
size = "medium",
46+
srcs = ["test/wheel_install_test.py"],
47+
args = ["$(location :kvcm_ops_wheel)"],
48+
data = [":kvcm_ops_wheel"],
49+
main = "test/wheel_install_test.py",
50+
)
51+
2752
py_test(
2853
name = "storage_util_test",
2954
srcs = ["test/storage_util_test.py"],
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import os
2+
import subprocess
3+
import sys
4+
import tempfile
5+
import unittest
6+
import venv
7+
from pathlib import Path
8+
9+
10+
class WheelInstallTest(unittest.TestCase):
11+
def setUp(self):
12+
self.wheel_path = Path(sys.argv[1]).resolve()
13+
self.temp_dir = tempfile.TemporaryDirectory()
14+
self.addCleanup(self.temp_dir.cleanup)
15+
16+
self.temp_path = Path(self.temp_dir.name)
17+
self.venv_path = self.temp_path / "venv"
18+
venv.EnvBuilder(with_pip=True).create(self.venv_path)
19+
self.python = self.venv_path / "bin" / "python"
20+
21+
self.env = os.environ.copy()
22+
for variable in ("PYTHONHOME", "PYTHONPATH", "PYTHONUSERBASE"):
23+
self.env.pop(variable, None)
24+
self.env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
25+
self.env["PYTHONNOUSERSITE"] = "1"
26+
27+
def run_command(self, *args):
28+
result = subprocess.run(
29+
args,
30+
cwd=self.temp_path,
31+
env=self.env,
32+
stdout=subprocess.PIPE,
33+
stderr=subprocess.STDOUT,
34+
text=True,
35+
)
36+
self.assertEqual(0, result.returncode, msg=result.stdout)
37+
return result.stdout
38+
39+
def test_install_resolves_requests_and_starts_http_command(self):
40+
self.run_command(
41+
self.python,
42+
"-I",
43+
"-c",
44+
"import importlib.util; "
45+
"assert importlib.util.find_spec('requests') is None",
46+
)
47+
48+
self.run_command(
49+
self.python,
50+
"-m",
51+
"pip",
52+
"install",
53+
"--no-input",
54+
self.wheel_path,
55+
)
56+
self.run_command(self.python, "-m", "pip", "check")
57+
self.run_command(
58+
self.python,
59+
"-I",
60+
"-c",
61+
"from importlib.metadata import version; "
62+
"assert version('requests') == '2.32.5'; "
63+
"import certifi, charset_normalizer, idna, requests, urllib3",
64+
)
65+
66+
top_level_help = self.run_command(
67+
self.python, "-I", "-m", "kvcm_ops", "--help"
68+
)
69+
self.assertIn("KVCM script entry", top_level_help)
70+
71+
http_command_help = self.run_command(
72+
self.python,
73+
"-I",
74+
"-m",
75+
"kvcm_ops",
76+
"list_instance",
77+
"--help",
78+
)
79+
self.assertIn("kvcm: list_intance.", http_command_help)
80+
81+
82+
if __name__ == "__main__":
83+
unittest.main(argv=[sys.argv[0]])
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import email
2+
import sys
3+
import unittest
4+
import zipfile
5+
from pathlib import Path
6+
7+
8+
class WheelMetadataTest(unittest.TestCase):
9+
@classmethod
10+
def setUpClass(cls):
11+
wheel_path = Path(sys.argv[1])
12+
requirements_path = Path(sys.argv[2])
13+
cls.expected_requirements = [
14+
line.strip()
15+
for line in requirements_path.read_text(encoding="utf-8").splitlines()
16+
if line.strip() and not line.lstrip().startswith("#")
17+
]
18+
19+
with zipfile.ZipFile(wheel_path) as archive:
20+
metadata_names = [
21+
name
22+
for name in archive.namelist()
23+
if name.endswith(".dist-info/METADATA")
24+
]
25+
if len(metadata_names) != 1:
26+
raise AssertionError(
27+
f"expected exactly one METADATA file, found {metadata_names}"
28+
)
29+
cls.metadata = email.message_from_bytes(archive.read(metadata_names[0]))
30+
31+
def test_declares_shared_runtime_requirements(self):
32+
self.assertEqual(["requests==2.32.5"], self.expected_requirements)
33+
self.assertEqual(
34+
self.expected_requirements,
35+
self.metadata.get_all("Requires-Dist", []),
36+
)
37+
38+
39+
if __name__ == "__main__":
40+
unittest.main(argv=[sys.argv[0]])

0 commit comments

Comments
 (0)