Skip to content

Commit

Permalink
Adding "perf_lock" Tests.
Browse files Browse the repository at this point in the history
Adding test of "perf lock" command with options called
"record", "report", "info", "script", "contention" with
all possible through YAML file.

Signed-off-by: Shaik Abdulla <[email protected]>
  • Loading branch information
FarooqAbdulla02 committed Apr 28, 2024
1 parent 9db2a75 commit efe2565
Show file tree
Hide file tree
Showing 2 changed files with 211 additions and 0 deletions.
160 changes: 160 additions & 0 deletions perf/perf_lock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#!/usr/bin/env python
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See LICENSE for more details.
#
# Copyright: 2024 IBM
# Author: Shaik Abdulla <[email protected]>

import os
import platform
from avocado import Test
from avocado.utils import distro, process, dmesg
from avocado.utils.software_manager.manager import SoftwareManager


class perf_lock(Test):

"""
Tests perf lock and it's options namely
record, report, info, script, contention
with all possible flags with the help of yaml file
:avocado: tags=perf,lock
"""

def setUp(self):
'''
Install the basic packages to support perf
'''

# Check for basic utilities
smm = SoftwareManager()
detected_distro = distro.detect()
self.distro_name = detected_distro.name

deps = ['gcc', 'make']
if self.distro_name in ['rhel', 'SuSE', 'fedora', 'centos']:
deps.extend(['perf'])
else:
self.cancel("Install the package for perf supported \
by %s" % detected_distro.name)
for package in deps:
if not smm.check_installed(package) and not smm.install(package):
self.cancel('%s is needed for the test to be run' % package)

self.record = self.params.get('name', default='')
self.option = self.params.get('option', default='')

# Check perf lock is available in the system.
output = process.run('perf list | awk \'/lock:contention*/\'',
shell=True).stdout.decode("utf-8")
if 'lock:contention_begin' in output or \
'lock:contention_end' in output:
self.log.info("perf lock is available")
else:
self.cancel('perf lock is not available')

# Clear the dmesg, by that we can capture the delta at the end of the
# test.
dmesg.clear_dmesg()

def run_cmd(self, cmd):
try:
process.run(cmd, ignore_status=False, sudo=True)
except process.CmdError as details:
self.fail("Command %s failed: %s" % (cmd, details))

def check_perfdata_file_exist(self):
'''
Function to verify "perf.data" file generated by
"perf record" command.
::rtype : True when file got generated by "perf record"
'''
if os.path.exists(self.output_file):
if not os.stat(self.output_file).st_size:
self.fail("%s sample not captured" % self.output_file)
return True

def get_kernel_version(self):
'''
Funtion to get kernel version based on distro type
'''

if 'rhel' in self.distro_name:
self.kernel_version = self.option + \
" /boot/vmlinuz-" + platform.uname()[2]
elif 'SuSE' in self.distro_name:
self.kernel_version = self.option + \
" /boot/vmlinux-" + platform.uname()[2]
return self.kernel_version

def test_lock(self):
# When input is used for report, then need to pass the file argument
# to the same file, record should log the data. So altering record,
# report options to have the proper arguments.

self.output_file = "perf.data"

# Record command

record_cmd = "perf lock record -o perf.data -a -v sleep 3 "
self.run_cmd(record_cmd)

# Report command
if self.record == 'report':
report_cmd = "perf lock %s %s " % (self.record, self.option)
if self.option in ["--kallsyms"]:
self.option = self.get_kernel_version()
report_cmd = "perf lock %s %s -E 3" % (self.record,
self.option)
if self.check_perfdata_file_exist:
self.run_cmd(report_cmd)

# Info command
elif self.record == 'info':
report_cmd = "perf lock %s %s" % (self.record, self.option)
if self.check_perfdata_file_exist:
self.run_cmd(report_cmd)

# Script command
elif self.record == 'script':
report_cmd = "perf lock %s %s %s" % (self.record,
self.option,
self.output_file)
if self.check_perfdata_file_exist:
self.run_cmd(report_cmd)

# contention command
elif self.record == 'contention':
report_cmd = "perf lock %s %s" % (self.record, self.option)
if self.option in ["--vmlinux"]:
self.option = self.get_kernel_version()
report_cmd = "perf lock %s %s" % (self.record, self.option)
elif self.option in ["-i"]:
report_cmd = "perf lock %s %s %s" % (self.record,
self.option,
self.output_file)

if self.check_perfdata_file_exist:
self.run_cmd(report_cmd)

# Verify dmesg
dmesg.collect_errors_dmesg(['WARNING: CPU:', 'Oops', 'Segfault',
'soft lockup', 'Unable to handle'])

def tearDown(self):
# Delete the temporary file
if os.path.isfile("perf.data"):
process.run('rm -f perf.data')
if os.path.isfile("perf.data.old"):
process.run('rm -f perf.data.old')
51 changes: 51 additions & 0 deletions perf/perf_lock.py.data/record_report.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
subsystem: !mux
record:
name: record
variants: !mux
all_cpus:
option: -a -v sleep 3
scheduling_message:
option: -- perf bench sched messaging

report:
name: report
variants: !mux
wait_field:
option: -k wait_total
all_fields:
option: -t -F acquired,contended,avg_wait,wait_total
locks_with_entries:
option: -c -D -E 5
vmlinux_full:
option: --kallsyms

info:
name: info
variants: !mux
threads_list:
option: -t
map_instances:
option: -m


script:
name: script
variants: !mux
input_data:
option: -i
contention:
name: contention
variants: !mux
contention_fields:
option: -C 0 -E 2 -F contended,wait_total -q
all_cpus_entires:
option: -a -t -E 1 -q
avg_wait_key:
option: -k avg_wait -l
trace_PID:
option: -p 1 -x ,
input_full:
option: -i
vmlinux_full:
option: --vmlinux

0 comments on commit efe2565

Please sign in to comment.