From 142fdf283d187e3ce89efd70d3feb4b606298d64 Mon Sep 17 00:00:00 2001 From: Martin Cermak Date: Fri, 21 Jan 2022 13:51:15 +0100 Subject: [PATCH] CI Gating: Add the python-probing testcase --- tests/Regression/python-probing/list.stp | 20 ++++++ tests/Regression/python-probing/main.fmf | 23 ++++++ tests/Regression/python-probing/runtest.sh | 81 ++++++++++++++++++++++ tests/Regression/python-probing/test.py | 3 + tests/Regression/python-probing/top.stp | 21 ++++++ 5 files changed, 148 insertions(+) create mode 100755 tests/Regression/python-probing/list.stp create mode 100644 tests/Regression/python-probing/main.fmf create mode 100755 tests/Regression/python-probing/runtest.sh create mode 100755 tests/Regression/python-probing/test.py create mode 100755 tests/Regression/python-probing/top.stp diff --git a/tests/Regression/python-probing/list.stp b/tests/Regression/python-probing/list.stp new file mode 100755 index 0000000..357fef6 --- /dev/null +++ b/tests/Regression/python-probing/list.stp @@ -0,0 +1,20 @@ +#!/usr/bin/stap -v +/* + Example usage of the Python systemtap tapset to show a nested view of all + Python function calls (and returns) across the whole system. + + Run this using + stap systemtap-example.stp + to instrument all Python processes on the system, or (for example) using + stap systemtap-example.stp -c COMMAND + to instrument a specific program (implemented in Python) +*/ +probe python.function.entry +{ + printf("%s => %s in %s:%d\n", thread_indent(1), funcname, filename, lineno); +} + +probe python.function.return +{ + printf("%s <= %s in %s:%d\n", thread_indent(-1), funcname, filename, lineno); +} diff --git a/tests/Regression/python-probing/main.fmf b/tests/Regression/python-probing/main.fmf new file mode 100644 index 0000000..1a5ec22 --- /dev/null +++ b/tests/Regression/python-probing/main.fmf @@ -0,0 +1,23 @@ +summary: Systemtap static probes test +description: | + This test checks basic functionality of Python's systemtap static + probes. It runs list & top systemtap scripts (examples from the + python rpm) and then a python script using the "random" module. + Finally it checks that the "random" module is correctly listed in + the output of both systemtap scripts. +contact: Petr Splichal +component: +- python +- systemtap +test: ./runtest.sh +framework: beakerlib +recommend: +- python +- python-debuginfo +- systemtap +- python2 +- python3 +- elfutils +duration: 15m +extra-summary: /CoreOS/python/Sanity/systemtap +extra-task: /CoreOS/python/Sanity/systemtap diff --git a/tests/Regression/python-probing/runtest.sh b/tests/Regression/python-probing/runtest.sh new file mode 100755 index 0000000..52c7091 --- /dev/null +++ b/tests/Regression/python-probing/runtest.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/python/Sanity/systemtap +# Description: Systemtap static probes test +# Author: Petr Splichal +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2011 Red Hat, Inc. All rights reserved. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# 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 the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include rhts environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +# Packages to be tested +PACKAGES="${PACKAGES:-python3}" +# Other required packages +REQUIRES=${REQUIRES:-} +# Binary name parametrized +PYTHON="${PYTHON:-python3}" + +package=$(rpm -qf --queryformat '%{name}\n' $(which $PYTHON)) +collection_path=$(which python | sed 's/\/usr\/bin\/python//') + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm --all + rlAssertRpm "systemtap" + rlLogInfo "Running on kernel: $(uname -r)" + rlRun "rpm -qa 'systemtap*'" 0 "Checking systemtap packages" + rlRun "TmpDir=\`mktemp -d\`" 0 "Creating tmp directory" + rlRun "cp list.stp top.stp test.py $TmpDir" 0 "Copying scripts" + rlRun "pushd $TmpDir" + rlPhaseEnd + + rlPhaseStartTest "Verifying ELF file for presence of .probes section" + for lib in ${collection_path}/usr/lib*/libpython*.so.* ; do + rlRun "eu-readelf -x .probes $lib" \ + 0 "Checking for .probes section within $lib" + done + rlPhaseEnd + + # Note that typically you need to be root to run "stap" (or be within + # an appropriate group) + for script in list top; do + rlPhaseStartTest "Test $script" + rlRun "rm -rf ~/.systemtap/cache" 0 "Cleaning cache" + rlRun "stap $script.stp -v -c \"$PYTHON test.py\" > $script" \ + 0 "Testing with $script.stp" + rlRun "tail -100 $script | col -b" 0 "Inspecting output" + if ! rlRun "grep '/usr/lib.*python.*random.py' '$script'" \ + 0 "Checking for random in the $script output"; then + rlRun "stap $script.stp -vvv -c \"$PYTHON test.py\" > $script" \ + 0 "Running $script.stp once more in verbose mode" + fi + rlPhaseEnd + done + + rlPhaseStartCleanup + rlRun "popd" + rlRun "rm -r $TmpDir" 0 "Removing tmp directory" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd diff --git a/tests/Regression/python-probing/test.py b/tests/Regression/python-probing/test.py new file mode 100755 index 0000000..65cc0b7 --- /dev/null +++ b/tests/Regression/python-probing/test.py @@ -0,0 +1,3 @@ +import random, time +print(random.random()) +time.sleep(3) diff --git a/tests/Regression/python-probing/top.stp b/tests/Regression/python-probing/top.stp new file mode 100755 index 0000000..b5645b2 --- /dev/null +++ b/tests/Regression/python-probing/top.stp @@ -0,0 +1,21 @@ +#!/usr/bin/stap -v + +global fn_calls; + +probe python.function.entry +{ + fn_calls[pid(), filename, funcname, lineno] += 1; +} + +probe timer.ms(1000) { + printf("\033[2J\033[1;1H") /* clear screen */ + printf("%6s %80s %6s %30s %6s\n", + "PID", "FILENAME", "LINE", "FUNCTION", "CALLS") + foreach ([pid, filename, funcname, lineno] in fn_calls- limit 1000) { + printf("%6d %80s %6d %30s %6d\n", + pid, filename, lineno, funcname, + fn_calls[pid, filename, funcname, lineno]); + } + + delete fn_calls; +}