added excessive logging threshold tests

pull/37274/head
Sourabh Singh 7 months ago
parent b1896a2136
commit bb2e7e44fc
  1. 5
      bazel/BUILD
  2. 45
      bazel/_logging_threshold_test_main.py
  3. 3
      bazel/internal_python_rules.bzl
  4. 75
      bazel/logging_threshold_test.bzl
  5. 6
      src/python/grpcio_tests/tests/unit/BUILD.bazel
  6. 56
      src/python/grpcio_tests/tests/unit/_single_module_tester.py

@ -24,3 +24,8 @@ filegroup(
name = "_gevent_test_main",
srcs = ["_gevent_test_main.py"],
)
filegroup(
name = "_logging_threshold_test_main",
srcs = ["_logging_threshold_test_main.py"],
)

@ -0,0 +1,45 @@
# Copyright 2024 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import tempfile
import sys
import subprocess
LOGGING_ERROR_THRESHOLD = 50
LOGGING_OUT_THRESHOLD = 20
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"USAGE: {sys.argv[0]} TARGET_MODULE", file=sys.stderr)
target_module = sys.argv[1]
command = [sys.executable, "./src/python/grpcio_tests/tests/unit/_single_module_tester.py", target_module]
with tempfile.TemporaryFile(mode="w+") as client_stdout:
with tempfile.TemporaryFile(mode="w+") as client_stderr:
result = subprocess.run(command, stdout=client_stdout, stderr=client_stderr, text=True)
client_stdout.seek(0)
client_stderr.seek(0)
stdout_count = len(client_stdout.readlines())
stderr_count = len(client_stderr.readlines())
if result.returncode != 0:
sys.exit('Test failure')
if stderr_count > LOGGING_ERROR_THRESHOLD or stdout_count > LOGGING_OUT_THRESHOLD:
sys.exit('Test failure')

@ -14,6 +14,7 @@
"""Python-related rules intended only for use internal to the repo."""
load("//bazel:gevent_test.bzl", "py_grpc_gevent_test")
load("//bazel:logging_threshold_test.bzl", "py_grpc_logging_threshold_test")
def internal_py_grpc_test(name, **kwargs):
"""Runs a test under all supported environments.
@ -28,6 +29,7 @@ def internal_py_grpc_test(name, **kwargs):
**kwargs
)
py_grpc_gevent_test(name, **kwargs)
py_grpc_logging_threshold_test(name, **kwargs)
suite_kwargs = {}
if "visibility" in kwargs:
@ -38,6 +40,7 @@ def internal_py_grpc_test(name, **kwargs):
tests = [
name + ".native",
name + ".gevent",
name + ".logging_threshold",
],
**suite_kwargs
)

@ -0,0 +1,75 @@
# Copyright 2023 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Houses py_grpc_logging_threshold_test.
"""
load("@grpc_python_dependencies//:requirements.bzl", "requirement")
_COPIED_MAIN_SUFFIX = ".logging_threshold.main"
def py_grpc_logging_threshold_test(
name,
srcs,
main = None,
deps = None,
data = None,
**kwargs):
"""Runs a Python unit test and checks amount of logging against a threshold.
Args:
name: The name of the test.
srcs: The source files.
main: The main file of the test.
deps: The dependencies of the test.
data: The data dependencies of the test.
**kwargs: Any other test arguments.
"""
if main == None:
if len(srcs) != 1:
fail("When main is not provided, srcs must be of size 1.")
main = srcs[0]
deps = [] if deps == None else deps
data = [] if data == None else data
lib_name = name + ".logging_threshold.lib"
native.py_library(
name = lib_name,
srcs = srcs,
)
augmented_deps = deps + [
":{}".format(lib_name),
]
# The main file needs to be in the same package as the test file.
copied_main_name = name + _COPIED_MAIN_SUFFIX
copied_main_filename = copied_main_name + ".py"
native.genrule(
name = copied_main_name,
srcs = ["//bazel:_logging_threshold_test_main.py"],
outs = [copied_main_filename],
cmd = "cp $< $@",
)
native.py_test(
name = name + ".logging_threshold",
args = [name],
data = data,
deps = augmented_deps,
srcs = [copied_main_filename],
main = copied_main_filename,
python_version = "PY3",
flaky = False,
**kwargs
)

@ -104,6 +104,11 @@ py_library(
srcs = ["_server_shutdown_scenarios.py"],
)
py_library(
name = "_single_module_tester",
srcs = ["_single_module_tester.py"],
)
py_library(
name = "_from_grpc_import_star",
srcs = ["_from_grpc_import_star.py"],
@ -124,6 +129,7 @@ py_library(
":_from_grpc_import_star",
":_rpc_test_helpers",
":_server_shutdown_scenarios",
":_single_module_tester",
":_signal_client",
":_tcp_proxy",
":resources",

@ -0,0 +1,56 @@
# Copyright 2024 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Sequence
import unittest
import sys
import os
import pkgutil
class SingleLoader(object):
def __init__(self, pattern: str):
loader = unittest.TestLoader()
self.suite = unittest.TestSuite()
tests = []
for importer, module_name, is_package in pkgutil.walk_packages([os.path.dirname(os.path.relpath(__file__))]):
if pattern in module_name:
module = importer.find_module(module_name).load_module(module_name)
tests.append(loader.loadTestsFromModule(module))
if len(tests) != 1:
raise AssertionError("Expected only 1 test module. Found {}".format(tests))
self.suite.addTest(tests[0])
def loadTestsFromNames(self, names: Sequence[str], module: str = None) -> unittest.TestSuite:
return self.suite
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"USAGE: {sys.argv[0]} TARGET_MODULE", file=sys.stderr)
target_module = sys.argv[1]
test_kwargs = {}
test_kwargs["verbosity"] = 3
loader = SingleLoader(target_module)
runner = unittest.TextTestRunner(**test_kwargs)
result = runner.run(loader.suite)
if not result.wasSuccessful():
sys.exit("Test failure.")
Loading…
Cancel
Save