From f03d1391b9f50a7aec8a8afe4c58a9d2237265e3 Mon Sep 17 00:00:00 2001 From: Xuchun Shang Date: Wed, 8 Jun 2022 22:13:19 +0800 Subject: [PATCH] tests: fix test-releated issue The tests have some issues: 1) Now the test scripts have no executive permission. 2) The tests need python module sh, yaml and sysstat. 3) For yaml module, the version previous 5.1 has no attribute FullLoader, so the api change will results in error. 4) The error message in cpu_throrrle test miss some message. 5) The output format of pidstat changes within different versions. So we use /proc/pid/stat to get the cpu usage. 6) For system with 2 cpus, the cpu0(both in the same socket) offline will lead to no sched_domain in test_cpu_bal, so we re-build the sched domain test. 7) Update the glob command. This patch fixes these issues. Signed-off-by: Xuchun Shang --- tests/bundles/ci | 2 +- tests/prep_env | 3 + tests/test_cpu_bal/assert | 45 ----------- tests/test_cpu_bal/patch.diff | 32 -------- tests/test_cpu_throttle/assert | 36 ++++++--- tests/test_domain_rebuild/assert | 107 +++++++++++++++++++++++++++ tests/test_domain_rebuild/patch.diff | 0 tests/test_public_var/assert | 9 ++- tests/test_sched_syscall/assert | 3 +- tests/test_var_uniformity/assert | 3 +- 10 files changed, 147 insertions(+), 93 deletions(-) delete mode 100644 tests/test_cpu_bal/assert delete mode 100644 tests/test_cpu_bal/patch.diff mode change 100644 => 100755 tests/test_cpu_throttle/assert create mode 100755 tests/test_domain_rebuild/assert create mode 100644 tests/test_domain_rebuild/patch.diff mode change 100644 => 100755 tests/test_public_var/assert mode change 100644 => 100755 tests/test_sched_syscall/assert mode change 100644 => 100755 tests/test_var_uniformity/assert diff --git a/tests/bundles/ci b/tests/bundles/ci index 58f50d6..567d7dc 100644 --- a/tests/bundles/ci +++ b/tests/bundles/ci @@ -2,5 +2,5 @@ quick_start public_var var_uniformity cpu_throttle -cpu_bal +domain_rebuild sched_syscall \ No newline at end of file diff --git a/tests/prep_env b/tests/prep_env index 33d039c..0521aff 100755 --- a/tests/prep_env +++ b/tests/prep_env @@ -16,7 +16,10 @@ fi uname_r=$(uname -r) uname_noarch=${uname_r%.*} yum install anolis-repos -y +yum install sysstat -y yum install podman yum-utils kernel-debuginfo-${uname_r} kernel-devel-${uname_r} --enablerepo=Plus-debuginfo --enablerepo=Plus -y +pip3 install sh +pip3 install pyyaml container=$(podman ps -a | awk '$NF=="plugsched"{print $1}') if [ -n "$container" ]; then diff --git a/tests/test_cpu_bal/assert b/tests/test_cpu_bal/assert deleted file mode 100644 index cc0bc87..0000000 --- a/tests/test_cpu_bal/assert +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sh -import sys -import subprocess -class CPUBalTest: - def setup_class(self): - print("CPU Balance test") - self.new_val = 117 - - def test_cpu_bal(self): - self.load_scheduler() - sh.echo('0', _out='/sys/devices/system/cpu/cpu0/online') - val = int(sh.cat('/proc/sys/kernel/sched_domain/cpu1/domain0/imbalance_pct').split()[0]) - if val != self.new_val: - self.error_handler() - - def load_scheduler(self): - scheduler_rpm = sh.glob(os.path.join('/tmp/work', 'scheduler*.rpm')) - if len(scheduler_rpm) != 1: - print("Please check your scheduler rpm"); - self.teardown_class() - sys.exit(1) - scheduler_rpm = scheduler_rpm[0] - sh.rpm('-ivh', scheduler_rpm) - - def error_handler(self): - print("The parameter imbalance_pct is not modified.") - print("CPU Balance test " + "\033[31mFAILED\033[0m") - self.teardown_class() - sys.exit(1) - - def teardown_class(self): - tmp = subprocess.Popen("lsmod | grep scheduler", shell=True, stdout=subprocess.PIPE) - if tmp.stdout.read() != b'': - sh.rpm('-e', 'scheduler-xxx') - -if __name__ == '__main__': - test_unit = CPUBalTest() - test_unit.setup_class() - test_unit.test_cpu_bal() - test_unit.teardown_class() - print("CPU Balance test " + "\033[32mPASS\033[0m") - diff --git a/tests/test_cpu_bal/patch.diff b/tests/test_cpu_bal/patch.diff deleted file mode 100644 index dbd53e2..0000000 --- a/tests/test_cpu_bal/patch.diff +++ /dev/null @@ -1,32 +0,0 @@ -# https://github.com/torvalds/linux/commit/2208cdaa56c957e20d8e16f28819aeb47851cb1e -# sched/fair: Reduce minimal imbalance threshold -# The 25% default imbalance threshold for DIE and NUMA domain is large -# enough to generate significant unfairness between threads. A typical -# example is the case of 11 threads running on 2x4 CPUs. The imbalance of -# 20% between the 2 groups of 4 cores is just low enough to not trigger -# the load balance between the 2 groups. We will have always the same 6 -# threads on one group of 4 CPUs and the other 5 threads on the other -# group of CPUS. With a fair time sharing in each group, we ends up with -# +20% running time for the group of 5 threads. - -# Consider decreasing the imbalance threshold for overloaded case where we -# use the load to balance task and to ensure fair time sharing. - -# Signed-off-by: Vincent Guittot -# Signed-off-by: Peter Zijlstra (Intel) -# Reviewed-by: Phil Auld -# Acked-by: Hillf Danton - -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_cpu_throttle/assert b/tests/test_cpu_throttle/assert old mode 100644 new mode 100755 index 50c28d2..435b397 --- a/tests/test_cpu_throttle/assert +++ b/tests/test_cpu_throttle/assert @@ -4,6 +4,8 @@ import subprocess import sh import os import sys +import time +from glob import glob class TestCPUThrottle: def setup_class(self): @@ -13,11 +15,13 @@ class TestCPUThrottle: def init_cgroup(self): cmd = "while :; do :; done" + self.start_time = time.time() self.child = subprocess.Popen(cmd, shell=True) sh.echo(self.child.pid, _out='/sys/fs/cgroup/cpu/test/cgroup.procs') def set_cfs_quota(self, t_us): sh.echo(t_us, _out='/sys/fs/cgroup/cpu/test/cpu.cfs_quota_us') + time.sleep(10) def test_all(self): self.set_cfs_quota('50000') @@ -29,42 +33,52 @@ class TestCPUThrottle: self.check_after_unload() def check_le_75(self): - sh.yum('-y', 'install', 'sysstat') - 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]) + cpu_util = self.get_cpu_util(self.child.pid) # assert cpu_util <= 75 if cpu_util > 75: self.error_handler(0, 75) def check_after_load(self): - scheduler_rpm = sh.glob(os.path.join('/tmp/work', 'scheduler*.rpm')) + scheduler_rpm = glob(os.path.join('/tmp/work', 'scheduler*.rpm')) if len(scheduler_rpm) != 1: print("Please check your scheduler rpm"); self.teardown_class() sys.exit(1) 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]) + cpu_util = self.get_cpu_util(self.child.pid) # assert cpu_util <= 75 if cpu_util > 75: self.error_handler(0, 75) def check_gt_75(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]) + cpu_util = self.get_cpu_util(self.child.pid) # assert cpu_util >= 75 if cpu_util < 75: self.error_handler(1, 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]) + cpu_util = self.get_cpu_util(self.child.pid) # assert cpu_util >= 75 if cpu_util < 75: self.error_handler(1, 75) + def get_cpu_util(self, pid): + def cpu_usage(): + time.sleep(0.5) + herts = float(sh.getconf('CLK_TCK')) + process_file = "/proc/" + str(pid) + "/stat" + process_stat = sh.cat(process_file).split() + total_time = float(process_stat[13]) + float(process_stat[14]) + elapsed_seconds = time.time() - self.start_time + return 100.0 * ((total_time / herts) / elapsed_seconds) + + cpu_util_1 = cpu_usage() + cpu_util_2 = cpu_usage() + cpu_util = (cpu_util_1 + cpu_util_2) / 2 + return cpu_util + def teardown_class(self): self.child.kill() self.child.wait() @@ -74,7 +88,7 @@ class TestCPUThrottle: sh.rpm('-e', 'scheduler-xxx') def error_handler(self, ty, bound): - err_msg = "CPU util should " + "less than" if ty == 0 else "greater than" + str(bound) + err_msg = "CPU util should " + ("less than" if ty == 0 else "greater than") + str(bound) print(err_msg) print("CPU throttle test " + "\033[31mFAILED\033[0m") self.teardown_class() diff --git a/tests/test_domain_rebuild/assert b/tests/test_domain_rebuild/assert new file mode 100755 index 0000000..367faf4 --- /dev/null +++ b/tests/test_domain_rebuild/assert @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 + +import os +import sh +import sys +import subprocess +import time +from glob import glob + +class CPUDomainReuildTest: + def setup_class(self): + print("CPU domain rebuild test") + self.init_cpu_set() + + def init_cpu_set(self): + self.cpu_set = [] + + def add_cpu(num): + cpu_state = "/sys/devices/system/cpu/cpu" + str(num) + "/online" + self.cpu_set.append(cpu_state) + + for i in range(0, 6, 2): + add_cpu(i) + + def test_cpu_rebuild(self): + self.record_orig_state() + self.load_scheduler() + self.record_state_after_load() + if self.load_domain_file != self.orig_domain_file or self.orig_state != self.load_state: + self.error_handler() + self.change_cpu_state() + self.record_after_change_cpu_state() + self.unload_scheduler() + self.record_state_after_unload() + if self.state_after_change_cpu != self.state_after_unload or self.domain_file_after_change_cpu != self.unload_domain_file: + self.error_handler() + + def record_after_change_cpu_state(self): + self.state_after_change_cpu = {} + self.record_data(self.state_after_change_cpu) + self.domain_file_after_change_cpu = set(sh.find("/proc/sys/kernel/sched_domain").split()) + + def record_state_after_load(self): + self.load_state = {} + self.record_data(self.load_state) + self.load_domain_file = set(sh.find("/proc/sys/kernel/sched_domain").split()) + + def record_state_after_unload(self): + self.state_after_unload = {} + self.record_data(self.state_after_unload) + self.unload_domain_file = set(sh.find("/proc/sys/kernel/sched_domain").split()) + + def record_orig_state(self): + self.orig_state = {} + self.record_data(self.orig_state) + self.orig_domain_file = set(sh.find("/proc/sys/kernel/sched_domain").split()) + + def record_data(self, data_arr): + for item in self.cpu_set: + if not os.path.exists(item): + continue + val = sh.cat(item).split()[0] + data_arr[item] = val + + def load_scheduler(self): + scheduler_rpm = glob(os.path.join('/tmp/work', 'scheduler*.rpm')) + if len(scheduler_rpm) != 1: + print("Please check your scheduler rpm"); + self.teardown_class() + sys.exit(1) + scheduler_rpm = scheduler_rpm[0] + sh.rpm('-ivh', scheduler_rpm) + + def unload_scheduler(self): + tmp = subprocess.Popen("lsmod | grep scheduler", shell=True, stdout=subprocess.PIPE) + if tmp.stdout.read() != b'': + sh.rpm('-e', 'scheduler-xxx') + + def change_cpu_state(self): + def reverse(val): + return "0" if val == "1" else "1" + + for k, v in self.orig_state.items(): + sh.echo(reverse(v), _out=k) + + def reload_cpu_state(self): + for k, v in self.orig_state.items(): + sh.echo(v, _out=k) + + def error_handler(self): + print("CPU domain rebuild test " + "\033[31mFAILED\033[0m") + self.unload_scheduler() + self.reload_cpu_state() + sys.exit(1) + + def teardown_class(self): + self.unload_scheduler() + self.reload_cpu_state() + +if __name__ == '__main__': + unit_test = CPUDomainReuildTest() + unit_test.setup_class() + unit_test.test_cpu_rebuild() + unit_test.teardown_class() + print("CPU domain rebuild test " + "\033[32mPASS\033[0m") + + diff --git a/tests/test_domain_rebuild/patch.diff b/tests/test_domain_rebuild/patch.diff new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_public_var/assert b/tests/test_public_var/assert old mode 100644 new mode 100755 index 276ef14..8ea7a09 --- a/tests/test_public_var/assert +++ b/tests/test_public_var/assert @@ -5,12 +5,13 @@ import sh import yaml import os import sys +from glob import glob class TestPublicVar: def setup_class(self): print("Public vars test") cur_sys = str(sh.uname('-r')).strip() - scheduler_rpm = sh.glob(os.path.join('/tmp/work', 'scheduler*.rpm')) + scheduler_rpm = glob(os.path.join('/tmp/work', 'scheduler*.rpm')) if len(scheduler_rpm) != 1: print("Please check your scheduler rpm"); self.teardown_class() @@ -20,7 +21,11 @@ class TestPublicVar: 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) + yaml_version = float(yaml.__version__) + if yaml_version >= 5.1: + config = yaml.load(f, Loader=yaml.FullLoader) + else: + config = yaml.load(f) self.public_vars = config['global_var']['extra_public'] cmd = "objdump -t " + module self.symtab = str(subprocess.check_output(cmd, shell=True)).split('\\n') diff --git a/tests/test_sched_syscall/assert b/tests/test_sched_syscall/assert old mode 100644 new mode 100755 index 1cb9043..419692c --- a/tests/test_sched_syscall/assert +++ b/tests/test_sched_syscall/assert @@ -4,6 +4,7 @@ import subprocess import sys import sh import os +from glob import glob class TestSchedSyscall: def setup_class(self): @@ -12,7 +13,7 @@ class TestSchedSyscall: self.child = subprocess.Popen(cmd, shell=True) def load_scheduler(self): - scheduler_rpm = sh.glob(os.path.join('/tmp/work', 'scheduler*.rpm')) + scheduler_rpm = glob(os.path.join('/tmp/work', 'scheduler*.rpm')) if len(scheduler_rpm) != 1: print("Please check your scheduler rpm"); self.teardown_class() diff --git a/tests/test_var_uniformity/assert b/tests/test_var_uniformity/assert old mode 100644 new mode 100755 index e7bd6cf..317db75 --- a/tests/test_var_uniformity/assert +++ b/tests/test_var_uniformity/assert @@ -5,6 +5,7 @@ import sh import os import subprocess import sys +from glob import glob class TestVarUniformity: def setup_class(self): @@ -45,7 +46,7 @@ class TestVarUniformity: dict[item] = str(sh.cat(item)).strip() def load_scheduler(self): - scheduler_rpm = sh.glob(os.path.join('/tmp/work', 'scheduler*.rpm')) + scheduler_rpm = glob(os.path.join('/tmp/work', 'scheduler*.rpm')) if len(scheduler_rpm) != 1: print("Please check your scheduler rpm"); self.teardown_class() -- Gitee