diff --git a/tests/test_function/readme.md b/tests/test_function/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..431f8d76bbe08748f49325db49be5f686fe9af0c --- /dev/null +++ b/tests/test_function/readme.md @@ -0,0 +1,15 @@ +## Test readme + +There are two types of tests, one is to use an empty patch, and the other needs to be patched first and then tested one by one. + +### Attention + +- You need to put the patch and the sourcecode of plugsched in the /tmp/work. + +- Need to install pytest. + +### Empty Patch +These tests are stored in the ./test_no_patch directory. Just enter the directory and enter the pytest command to run all the tests. + +### Need Patch +These tests are stored in the ./test_need_patch directory. Each subdirectory nested in it is a separate test unit. You need to use the patch command to modify the code, and then run the corresponding test script. diff --git a/tests/test_function/test_need_patch/cpu_hotplug/imbalance_pct.patch b/tests/test_function/test_need_patch/cpu_hotplug/imbalance_pct.patch new file mode 100644 index 0000000000000000000000000000000000000000..bd6d9636acd6126f8741a6097797e0cae4dff5e0 --- /dev/null +++ b/tests/test_function/test_need_patch/cpu_hotplug/imbalance_pct.patch @@ -0,0 +1,16 @@ +scheduler/kernel/sched/mod/topology.c | 2 +- +1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scheduler/kernel/sched/mod/topology.c b/scheduler/kernel/sched/mod/topology.c +index 249bec7b0a4c..41df62884cea 100644 +--- a/scheduler/kernel/sched/mod/topology.c ++++ b/scheduler/kernel/sched/mod/topology.c +@@ -1097,7 +1097,7 @@ sd_init(struct sched_domain_topology_level *tl, + .min_interval = sd_weight, + .max_interval = 2*sd_weight, + .busy_factor = 32, +- .imbalance_pct = 125, ++ .imbalance_pct = 117, + + .cache_nice_tries = 0, + diff --git a/tests/test_function/test_need_patch/cpu_hotplug/test_cpu_hotplug.py b/tests/test_function/test_need_patch/cpu_hotplug/test_cpu_hotplug.py new file mode 100644 index 0000000000000000000000000000000000000000..af6d180c8e0409414d356be56b326e4c5901aff3 --- /dev/null +++ b/tests/test_function/test_need_patch/cpu_hotplug/test_cpu_hotplug.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +import os +import sh +import argparse +class CPUBalTest: + def __init__(self, new_val): + self.new_val = new_val + + def check(self): + orig = sh.cat('/proc/sys/kernel/sched_domain/cpu1/domain0/imbalance_pct').split()[0] + print("The original value is " + orig) + sh.echo('0', _out='/sys/devices/system/cpu/cpu0/online') + res = sh.cat('/proc/sys/kernel/sched_domain/cpu1/domain0/imbalance_pct').split()[0] + if res == self.new_val: + print("The parameter imbalance_pct has been modified correctly.") + else: + print("The parameter imbalance_pct has been modified a wrong value: " + res) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-v', '--value') + args = parser.parse_args() + cbt = CPUBalTest(args.value) + cbt.check() diff --git a/tests/test_function/test_no_patch/test_cpu_throttle.py b/tests/test_function/test_no_patch/test_cpu_throttle.py new file mode 100644 index 0000000000000000000000000000000000000000..752589a6b0d07f4fac5b66143b9185ebf158a865 --- /dev/null +++ b/tests/test_function/test_no_patch/test_cpu_throttle.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 + +import subprocess +import sh +import os +import pytest + +class TestCPUThrottle: + def setup_class(self): + print("CPU throttle test") + sh.mkdir('/sys/fs/cgroup/cpu/test') + sh.echo('50000', _out='/sys/fs/cgroup/cpu/test/cpu.cfs_quota_us') + cmd = "while :; do :; done" + self.child = subprocess.Popen(cmd, shell=True) + sh.echo(self.child.pid, _out='/sys/fs/cgroup/cpu/test/cgroup.procs') + + def test_all(self): + self.check_le_70() + self.check_after_load() + self.check_gt_75() + self.check_after_unload() + + def check_le_70(self): + cmd = "pidstat -h -u -p " + str(self.child.pid) + " 1 1 | awk '{print $7}' | tail -1" + cpu_util = float(subprocess.check_output(cmd, shell=True).split()[0]) + pytest.assume(cpu_util <= 75) + + def check_after_load(self): + scheduler_rpm = sh.glob(os.path.join('/tmp/work', 'scheduler*.rpm')) + assert scheduler_rpm != [] + scheduler_rpm = scheduler_rpm[0] + sh.rpm('-ivh', scheduler_rpm) + cmd = "pidstat -h -u -p " + str(self.child.pid) + " 1 1 | awk '{print $7}' | tail -1" + cpu_util = float(subprocess.check_output(cmd, shell=True).split()[0]) + pytest.assume(cpu_util <= 75) + + def check_gt_75(self): + sh.echo('100000', _out="/sys/fs/cgroup/cpu/test/cpu.cfs_quota_us") + cmd = "pidstat -h -u -p " + str(self.child.pid) + " 1 1 | awk '{print $7}' | tail -1" + cpu_util = float(subprocess.check_output(cmd, shell=True).split()[0]) + pytest.assume(cpu_util >= 75) + + def check_after_unload(self): + sh.rpm('-e', 'scheduler-xxx') + cmd = "pidstat -h -u -p " + str(self.child.pid) + " 1 1 | awk '{print $7}' | tail -1" + cpu_util = float(subprocess.check_output(cmd, shell=True).split()[0]) + pytest.assume(cpu_util >= 75) + + def teardown_class(self): + self.child.kill() + self.child.wait() + sh.rmdir("/sys/fs/cgroup/cpu/test") + + + diff --git a/tests/test_function/test_no_patch/test_syms.py b/tests/test_function/test_no_patch/test_syms.py new file mode 100644 index 0000000000000000000000000000000000000000..7bd6a7f67f06ad3a511ebda92c3d9471fa5ec7af --- /dev/null +++ b/tests/test_function/test_no_patch/test_syms.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 + +from asyncio import subprocess +import sh +import yaml +import os +import pytest + +class TestVarInheri1: + def setup_class(self): + print("Check over symbols of global vars") + cur_sys = str(sh.uname('-r')).strip() + scheduler_rpm = sh.glob(os.path.join('/tmp/work', 'scheduler*.rpm')) + assert scheduler_rpm != [] + scheduler_rpm = scheduler_rpm[0] + sh.rpm('-ivh', scheduler_rpm) + module = '/var/plugsched/' + cur_sys + '/scheduler.ko' + yaml_file = '/tmp/work/scheduler/working/sched_boundary.yaml' + with open(yaml_file, 'r') as f: + config = yaml.load(f, Loader=yaml.FullLoader) + self.public_vars = config['global_var']['extra_public'] + cmd = "objdump -t " + module + self.symtab = str(subprocess.check_output(cmd, shell=True)).split('\\n') + + + def test_syms(self): + for var in self.public_vars: + for cur_line in self.symtab: + if cur_line == '' or cur_line.split()[-1] != var: + continue + pytest.assume('*UND*' in cur_line) + break + + def teardown_class(self): + sh.rpm('-e', 'scheduler-xxx') + diff --git a/tests/test_function/test_no_patch/test_vars_inheritance.py b/tests/test_function/test_no_patch/test_vars_inheritance.py new file mode 100644 index 0000000000000000000000000000000000000000..6bd935606dbc6d28dc6871a1b6332ea7862df177 --- /dev/null +++ b/tests/test_function/test_no_patch/test_vars_inheritance.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +from typing import Dict +import sh +import os +import subprocess +import pytest + +class TestVarInheri2: + def setup_class(self): + print("Global vars inheritance test") + self.global_name = [ + "/proc/sys/kernel/sched_child_runs_first", + "/proc/sys/kernel/sched_min_granularity_ns", + "/proc/sys/kernel/sched_latency_ns", + "/proc/sys/kernel/sched_wakeup_granularity_ns", + "/proc/sys/kernel/sched_tunable_scaling", + "/proc/sys/kernel/sched_migration_cost_ns", + "/proc/sys/kernel/sched_nr_migrate", + "/proc/sys/kernel/sched_schedstats", + "/proc/sys/kernel/numa_balancing_scan_delay_ms", + "/proc/sys/kernel/numa_balancing_scan_period_min_ms", + "/proc/sys/kernel/numa_balancing_scan_period_max_ms", + "/proc/sys/kernel/numa_balancing_scan_size_mb", + "/proc/sys/kernel/numa_balancing", + "/proc/sys/kernel/sched_rt_period_us", + "/proc/sys/kernel/sched_rt_runtime_us", + "/proc/sys/kernel/sched_rr_timeslice_ms", + "/proc/sys/kernel/sched_autogroup_enabled", + "/proc/sys/kernel/sched_cfs_bandwidth_slice_us", + "/sys/kernel/debug/sched_debug", + ] + + def before_change(self): + self.orig_data = {} + self.record_data(self.orig_data) + self.load_scheduler() + self.data_after_load = {} + self.record_data(self.data_after_load) + + def record_data(self, dict: Dict): + for item in self.global_name: + if not os.path.exists(item): + continue + dict[item] = str(sh.cat(item)).strip() + + def load_scheduler(self): + scheduler_rpm = sh.glob(os.path.join('/tmp/work', 'scheduler*.rpm')) + assert scheduler_rpm != [] + scheduler_rpm = scheduler_rpm[0] + sh.rpm('-ivh', scheduler_rpm) + + def after_change_unload(self): + self.modify_data() + self.data_after_modified = {} + self.record_data(self.data_after_modified) + sh.rpm('-e', 'scheduler-xxx') + self.data_after_unload = {} + self.record_data(self.data_after_unload) + + def modify_data(self): + def reverse(ch): + if ch.isdigit(): + return '1' if ch == '0' else str(int(ch) - 1) + return 'N' if ch == 'Y' else 'Y' + + for k, v in self.orig_data.items(): + sh.echo(reverse(v), _out=k) + + def teardown_class(self): + res = subprocess.Popen("lsmod | grep scheduler", shell=True, stdout=subprocess.PIPE) + if res.stdout.read() != b'': + subprocess.Popen('rpm -e scheduler-xxx', shell=True) + + def recover(self): + for k, v in self.orig_data.items(): + sh.echo(v, _out=k) + + def test_data_inheri(self): + self.before_change() + pytest.assume(self.orig_data == self.data_after_load) + self.after_change_unload() + pytest.assume(self.data_after_modified == self.data_after_unload) + self.recover() +