xref: /aosp_15_r20/kernel/tests/net/test/util.py (revision 2f2c4c7ab4226c71756b9c31670392fdd6887c4f)
1# Copyright 2017 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Utilities for kernel net tests."""
16
17import ctypes
18
19
20def GetSysprop(name):
21  PROP_VALUE_MAX = 92
22  libc = ctypes.CDLL(ctypes.util.find_library("c"), use_errno=True)
23  name = ctypes.create_string_buffer(name)
24  value = ctypes.create_string_buffer(PROP_VALUE_MAX)
25  libc.__system_property_get(name, value)
26  return value.value
27
28
29def VendorApiLevelIsAtLeast(min_level):
30  try:
31    level = int(GetSysprop(b"ro.vendor.api_level"))
32  except AttributeError:
33    return True
34  return level >= min_level
35
36
37def GetPadLength(block_size, length):
38  return (block_size - (length % block_size)) % block_size
39
40
41def InjectParameterizedTest(cls, param_list, name_generator):
42  """Injects parameterized tests into the provided class
43
44  This method searches for all tests that start with the name "ParamTest",
45  and injects a test method for each set of parameters in param_list. Names
46  are generated via the use of the name_generator.
47
48  Args:
49    cls: the class for which to inject all parameterized tests
50    param_list: a list of tuples, where each tuple is a combination of
51        of parameters to test (i.e. representing a single test case)
52    name_generator: A function that takes a combination of parameters and
53        returns a string that identifies the test case.
54  """
55  param_test_names = [name for name in dir(cls) if name.startswith("ParamTest")]
56
57  # Force param_list to an actual list; otherwise itertools.Product will hit
58  # the end, resulting in only the first ParamTest* method actually being
59  # parameterized
60  param_list = list(param_list)
61
62  # Parameterize each test method starting with "ParamTest"
63  for test_name in param_test_names:
64    func = getattr(cls, test_name)
65
66    for params in param_list:
67      # Give the test method a readable, debuggable name.
68      param_string = name_generator(*params)
69      new_name = "%s_%s" % (func.__name__.replace("ParamTest", "test"),
70                            param_string)
71      new_name = new_name.replace("(", "-").replace(")", "")  # remove parens
72
73      # Inject the test method
74      setattr(cls, new_name, _GetTestClosure(func, params))
75
76
77def _GetTestClosure(func, params):
78  """ Creates a no-argument test method for the given function and parameters.
79
80  This is required to be separate from the InjectParameterizedTest method, due
81  to some interesting scoping issues with internal function declarations. If
82  left in InjectParameterizedTest, all the tests end up using the same
83  instance of TestClosure
84
85  Args:
86    func: the function for which this test closure should run
87    params: the parameters for the run of this test function
88  """
89
90  def TestClosure(self):
91    func(self, *params)
92
93  return TestClosure
94