Enable CI gating

This commit is contained in:
Martin Cermak 2021-04-21 15:27:19 +02:00
parent 36f9c5a1f5
commit 2eb398d8d5
16 changed files with 697 additions and 0 deletions

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

20
gating.yaml Normal file
View File

@ -0,0 +1,20 @@
--- !Policy
product_versions:
- fedora-*
decision_context: bodhi_update_push_stable
subject_type: koji_build
rules:
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional}
- !PassingTestCaseRule {test_case_name: baseos-qe.koji-build.scratch-build.validation}
--- !Policy
product_versions:
- rhel-8
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}

6
plans/ci.fmf Normal file
View File

@ -0,0 +1,6 @@
summary: CI Gating Plan
discover:
how: fmf
directory: tests
execute:
how: beakerlib

View File

@ -0,0 +1,19 @@
CPP=g++
#DYNINST_ROOT=/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst
LINK=-L/opt/rh/devtoolset-3/root/usr/lib$(BITS)/dyninst -L/opt/rh/devtoolset-3/root/usr/lib$(BITS)/dyninst/lib
# -ldyninstAPI -ldynC -ldl
#LINK=-L/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst -L/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst/lib -ldyninstAPI -ldl
INCLUDE=-I/opt/rh/devtoolset-3/root/usr/include/dyninst
LINK2=-ldyninstAPI -ldl -lboost_system
all: mutatee mutator
clean:
rm mutatee mutator
mutatee: mutatee.cpp
$(CPP) -g -o mutatee mutatee.cpp
mutator: mutator.cpp
$(CPP) -g -o mutator $(INCLUDE) $(LINK) $(LINK2) mutator.cpp

View File

@ -0,0 +1,49 @@
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
using namespace std;
int a = 0;
void incr(void)
{
a++;
}
void incr2(void)
{
a += 100;
}
int function_name(void)
{
fprintf(stderr, "FUNCTION EXECUTED. VALUE = %i\n", a);
}
int main(int argc, char **argv)
{
int n = 10, i;
FILE *f = fopen("RESULT.log", "w");
if(argc > 1)
{
if((n = atoi(argv[1])) <= 0)
n = 10;
}
else
n = 10;
for(i = 0; i < n; i++)
{
function_name();
sleep(3);
}
if((a > 200) && (a % 100 > 0))
fprintf(f, "MUTATION OK.\n");
else
fprintf(f, "MUTATION FAILED.\n");
fclose(f);
return !a;
}

View File

@ -0,0 +1,115 @@
#include <cstdlib>
#include <cstdio>
#include <string>
#include <vector>
#include <iostream>
// dyninst libraries
#include "BPatch.h"
#include "BPatch_addressSpace.h"
#include "BPatch_process.h"
#include "BPatch_function.h"
#include "BPatch_point.h"
//#include "BPatch_flowGraph.h"
using namespace std;
int main(int argc, char **argv)
{
BPatch bpatch1, bpatch2;
int pid;
BPatch_process *app_proc;
BPatch_addressSpace *aspace;
BPatch_image *image;
// check the options
if(argc != 2)
{
cerr << "ERROR ## Missing command line args. Use PID of the process you want to attach.\n";
return 1;
}
pid = atoi(argv[1]);
if(pid == 0)
{
cerr << "ERROR ## Wrong PID " << pid << ", please use another.\n";
return 2;
}
cerr << "TAKE1 A\n";
// let's go...
app_proc = bpatch1.processAttach(NULL, pid);
cerr << "TAKE1 B\n";
aspace = app_proc;
cerr << "TAKE1 C\n";
image = aspace->getImage();
cerr << "TAKE1 D\n";
/* BPatch_Set<BPatch_opCode> access_types;
access_types.insert(BPatch_opLoad);
access_types.insert(BPatch_opStore);
*/
vector<BPatch_function *> functions, incr_functions;
vector<BPatch_point *> *points;
image->findFunction("function_name", functions);
cerr << "TAKE1 E\n";
points = functions[0]->findPoint(BPatch_entry);
cerr << "TAKE1 F\n";
// create snippet
image->findFunction("incr", incr_functions);
cerr << "TAKE1 G\n";
vector<BPatch_snippet *> incr_args;
BPatch_funcCallExpr incr_call(*(incr_functions[0]), incr_args);
aspace->insertSnippet(incr_call, *points);
cerr << "TAKE1 H\n";
app_proc->continueExecution();
cerr << "TAKE1 I\n";
sleep(4);
app_proc->detach(true);
cout << "FIRST MUTATION DONE. MUTATOR IS DOING THE SECOND ONE...\n";
sleep(4);
cerr << "TAKE2 A\n";
// let's go...
app_proc = bpatch2.processAttach(NULL, pid);
cerr << "TAKE2 B\n";
aspace = app_proc;
cerr << "TAKE2 C\n";
image = aspace->getImage();
cerr << "TAKE2 D\n";
/* BPatch_Set<BPatch_opCode> access_types;
access_types.insert(BPatch_opLoad);
access_types.insert(BPatch_opStore);
*/
vector<BPatch_function *> functions2, incr_functions2;
vector<BPatch_point *> *points2;;
image->findFunction("function_name", functions2);
cerr << "TAKE2 E\n";
points2 = functions2[0]->findPoint(BPatch_exit);
cerr << "TAKE2 F\n";
// create snippet
image->findFunction("incr2", incr_functions2);
cerr << "TAKE2 G\n";
vector<BPatch_snippet *> incr_args2;
BPatch_funcCallExpr incr_call2(*(incr_functions2[0]), incr_args2);
aspace->insertSnippet(incr_call2, *points2);
cerr << "TAKE2 H\n";
app_proc->continueExecution();
cerr << "TAKE2 I\n";
app_proc->detach(true);
cout << "SECOND MUTATION DONE. MUTATOR IS GOING...\n";
return 0;
}

View File

@ -0,0 +1,17 @@
CPP=g++
#DYNINST_ROOT=/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst
##LINK=-L/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst -L/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst/lib -ldyninstAPI -ldynC -ldl
#LINK=-L/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst -L/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst/lib -ldyninstAPI -ldl
#INCLUDE=-I/opt/rh/devtoolset-2/root/usr/include/dyninst
LINK2=-ldyninstAPI -ldl -lboost_system
all: mutatee mutator
clean:
rm mutatee mutator
mutatee: mutatee.cpp
$(CPP) -g -o mutatee mutatee.cpp
mutator: mutator.cpp
$(CPP) -g -o mutator $(INCLUDE) $(LINK) $(LINK2) mutator.cpp

View File

@ -0,0 +1,6 @@
DYNINSTAPI_RT_LIB=/opt/rh/devtoolset-3/root/usr/lib64/dyninst/libdyninstAPI_RT.so
export DYNINSTAPI_RT_LIB
if [[ ! $LD_LIBRARY_PATH =~ .*dyninst.* ]]; then
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/dyninst
fi
export LD_LIBRARY_PATH

View File

@ -0,0 +1,44 @@
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
using namespace std;
int a = 0;
void incr(void)
{
a++;
}
int function_name(void)
{
fprintf(stderr, "FUNCTION EXECUTED. VALUE = %i\n", a);
}
int main(int argc, char **argv)
{
int n = 10, i;
FILE *f = fopen("RESULT.log", "w");
if(argc > 1)
{
if((n = atoi(argv[1])) <= 0)
n = 10;
}
else
n = 10;
for(i = 0; i < n; i++)
{
function_name();
sleep(3);
}
if(a)
fprintf(f, "MUTATION OK.\n");
else
fprintf(f, "MUTATION FAILED.\n");
fclose(f);
return !a;
}

View File

@ -0,0 +1,73 @@
#include <cstdlib>
#include <cstdio>
#include <string>
#include <vector>
#include <iostream>
// dyninst libraries
#include "BPatch.h"
#include "BPatch_addressSpace.h"
#include "BPatch_process.h"
#include "BPatch_function.h"
#include "BPatch_point.h"
//#include "BPatch_flowGraph.h"
using namespace std;
BPatch bpatch;
int main(int argc, char **argv)
{
int pid;
BPatch_process *app_proc;
BPatch_addressSpace *aspace;
BPatch_image *image;
// check the options
if(argc != 2)
{
cerr << "ERROR ## Missing command line args. Use PID of the process you want to attach.\n";
return 1;
}
pid = atoi(argv[1]);
if(pid == 0)
{
cerr << "ERROR ## Wrong PID " << pid << ", please use another.\n";
return 2;
}
// let's go...
app_proc = bpatch.processAttach(NULL, pid);
aspace = app_proc;
image = aspace->getImage();
/* BPatch_Set<BPatch_opCode> access_types;
access_types.insert(BPatch_opLoad);
access_types.insert(BPatch_opStore);
*/
vector<BPatch_function *> functions, incr_functions;
vector<BPatch_point *> *points;
image->findFunction("function_name", functions);
points = functions[0]->findPoint(BPatch_entry);
// create snippet
image->findFunction("incr", incr_functions);
vector<BPatch_snippet *> incr_args;
BPatch_funcCallExpr incr_call(*(incr_functions[0]), incr_args);
aspace->insertSnippet(incr_call, *points);
app_proc->continueExecution();
#ifdef __PPC__
// PPC detach removes snippets, so wait
bpatch.waitForStatusChange();
#endif
app_proc->detach(true);
cout << "MUTATION DONE. MUTATOR IS GOING...\n";
return 0;
}

View File

@ -0,0 +1,16 @@
summary: The test does basic instrumentation on binaries.
description: ''
contact:
- Michael Petlan <mpetlan@redhat.com>
component:
- dyninst
test: ./runtest.sh
framework: beakerlib
recommend:
- dyninst
- dyninst-devel
- gcc
- gcc-c++
duration: 12m
extra-summary: /tools/dyninst/Sanity/smoke-test
extra-task: /tools/dyninst/Sanity/smoke-test

View File

@ -0,0 +1,207 @@
#!/bin/bash
# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /tools/dyninst/Sanity/smoke-test
# Description: The test does basic instrumentation on binaries.
# Author: Michael Petlan <mpetlan@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2013 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 Beaker environment
. /usr/share/beakerlib/beakerlib.sh || exit 1
PACKAGE="dyninst"
rlJournalStart
rlPhaseStartSetup
rlRun "TMPD=$(mktemp -d)"
rlRun "cp -r dynamic dynamic-double static $TMPD/"
rlRun "pushd $TMPD"
# load the proper environment - set the variables
# When using dyninst, we have to have LD_LIBRARY_PATH set to dyninst's directory
# and DYNINSTAPI_RT_LIB should keep the path of libdyninstAPI_RT.so.8.0 shared library.
# After having this set properly, an application what uses dyninst, can be compiled and run.
test -e "/usr/lib64" && BITS="64" || BITS=""
ARCH=`rlGetPrimaryArch`
rlAssertRpm $PACKAGE
DYNINST_ROOT="/usr/lib$BITS/dyninst"
INCLUDE="-I/usr/include/dyninst"
LINK="-L/usr/lib$BITS/dyninst -L/usr/lib$BITS/dyninst/lib"
echo $LD_LIBRARY_PATH | grep "$DYNINST_ROOT"
if [ $? -ne 0 ]; then
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$DYNINST_ROOT"
fi
# the API runtime library path should be available from rpmquery
if [ `rpmquery -l $PACKAGE.$ARCH | grep API_RT | wc -l` -eq 1 ]; then
# if there's only one file, we may accept that
DYNINSTAPI_RT_LIB=`rpmquery -l $PACKAGE.$ARCH | grep API_RT`
else
# sometimes there're many links to the API_RT lib, so we have to choose the proper file
for rtlib in `rpmquery -l $PACKAGE.$ARCH | grep API_RT`; do
test -L $rtlib || DYNINSTAPI_RT_LIB="$rtlib"
done
fi
export DYNINSTAPI_RT_LIB
if [[ ! $LD_LIBRARY_PATH =~ .*dyninst.* ]]; then
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/dyninst
fi
export LD_LIBRARY_PATH
# compile both static and dynamic test
for TC in static dynamic dynamic-double; do
cd $TC
rlRun "make BITS=\"$BITS\" DYNINST_ROOT=\"$DYNINST_ROOT\" INCLUDE=\"$INCLUDE\" LINK=\"$LINK\"" 0 "Compiling $TC dyninst example."
cd ..
done
# IMPORTANT: We have to make sure, that some SELinux bools are set right (see dyninst docs)
#
# We need:
# allow_execmod --> on
# allow_execstack --> on
# deny_ptrace --> off
#
# Note: The bool deny_ptrace is not present in RHEL yet.
#
SELINUX_STATUS=`sestatus | grep "SELinux status" | awk '{ print $3; }'`
if [[ "$SELINUX_STATUS" == "enabled" ]]; then
rlLog "SELINUX IS ENABLED."
SEBOOL_ALLOW_EXECMOD=`getsebool allow_execmod`
SEBOOL_ALLOW_EXECSTACK=`getsebool allow_execstack`
SEBOOL_DENY_PTRACE=`getsebool deny_ptrace`
if [[ "$SEBOOL_ALLOW_EXECMOD" =~ "> off" ]]; then
rlLog "SELINUX: We need to set allow_execmod to on."
setsebool allow_execmod on
SEBOOL_ALLOW_EXECMOD="off"
else
rlLog "SELINUX: $SEBOOL_ALLOW_EXECMOD -- already OK."
fi
if [[ "$SEBOOL_ALLOW_EXECSTACK" =~ "> off" ]]; then
rlLog "SELINUX: We need to set allow_execstack to on."
setsebool allow_execstack on
SEBOOL_ALLOW_EXECSTACK="off"
else
rlLog "SELINUX: $SEBOOL_ALLOW_EXECSTACK -- already OK."
fi
if [[ "$SEBOOL_DENY_PTRACE" =~ "> on" ]]; then
rlLog "SELINUX: We need to set deny_ptrace to off."
setsebool deny_ptrace off
SEBOOL_DENY_PTRACE="on"
else
if [ -z "$SEBOOL_DENY_PTRACE" ]; then
rlLog "SELINUX: deny_ptrace does not exist -- OK."
else
rlLog "SELINUX: $SEBOOL_DENY_PTRACE -- already OK."
fi
fi
else
rlLog "SELINUX IS DISABLED. We do not have to change anything."
fi
# Checking for lahf instruction support (bz1134843 workaround)
ARCH=`uname -i`
if [[ "$ARCH" =~ "86" ]]; then
IS_LAHF_SUPPORTED=`cat /proc/cpuinfo | grep lahf`
if [ -z "$IS_LAHF_SUPPORTED" ]; then
rlLogWarning "The CPU does not support needed LAHF instruction."
fi
fi
rlPhaseEnd
rlPhaseStartTest "Testing static instrumentation"
cd static
rlRun "./mutator"
rlAssertExists "mutated"
RESULT=`./mutated`
if [[ "$RESULT" == "MUTATION OK." ]]; then
rlPass "Instrumentation PASSed."
else
rlFail "Instrumentation FAILed."
fi
cd ..
rlPhaseEnd
rlPhaseStartTest "Testing dynamic instrumentation"
cd dynamic
./mutatee 10 &
PID=$!
# export DYNINST_DEBUG_STARTUP=1
# export DYNINST_DEBUG_RTLIB=1
# export DYNINST_DEBUG_CRASH=1
# export DYNINST_DEBUG_BPATCH=1
./mutator $PID
sleep 50
RESULT=`cat RESULT.log`
if [[ "$RESULT" == "MUTATION OK." ]]; then
rlPass "Instrumentation PASSed."
else
rlFail "Instrumentation FAILed."
fi
cd ..
rlPhaseEnd
rlPhaseStartTest "Testing dynamic double instrumentation"
# This case needs to have the DYNINSTAPI_RT_LIB variable pointing to a regular file
# not to symlink. So it has to be hacked a little
export DYNINSTAPI_RT_LIB=`readlink -fn $DYNINSTAPI_RT_LIB`
cd dynamic-double
./mutatee 10 &
PID=$!
# export DYNINST_DEBUG_STARTUP=1
# export DYNINST_DEBUG_RTLIB=1
# export DYNINST_DEBUG_CRASH=1
# export DYNINST_DEBUG_BPATCH=1
./mutator $PID
sleep 50
RESULT=`cat RESULT.log`
if [[ "$RESULT" == "MUTATION OK." ]]; then
rlPass "Instrumentation PASSed."
else
rlFail "Instrumentation FAILed."
fi
cd ..
rlPhaseEnd
rlPhaseStartCleanup
rlRun "popd"
rlRun "rm -r $TMPD"
# restore the SELinux bools, if they were changed
if [[ "$SEBOOL_ALLOW_EXECMOD" == "off" ]]; then
rlLog "Restoring SELinux bool allow_execmod to $SEBOOL_ALLOW_EXECMOD."
setsebool allow_execmod $SEBOOL_ALLOW_EXECMOD
fi
if [[ "$SEBOOL_ALLOW_EXECSTACK" == "off" ]]; then
rlLog "Restoring SELinux bool allow_execstack to $SEBOOL_ALLOW_EXECSTACK."
setsebool allow_execstack $SEBOOL_ALLOW_EXECSTACK
fi
if [[ "$SEBOOL_DENY_PTRACE" == "on" ]]; then
rlLog "Restoring SELinux bool deny_ptrace to $SEBOOL_DENY_PTRACE."
setsebool deny_ptrace $SEBOOL_DENY_PTRACE
fi
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

View File

@ -0,0 +1,17 @@
CPP=g++
#DYNINST_ROOT=/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst
##LINK=-L/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst -L/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst/lib -ldyninstAPI -ldynC -ldl
#LINK=-L/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst -L/opt/rh/devtoolset-2/root/usr/lib$(BITS)/dyninst/lib -ldyninstAPI -ldl
#INCLUDE=-I/opt/rh/devtoolset-2/root/usr/include/dyninst
LINK2=-ldyninstAPI -ldl -lboost_system
all: mutatee mutator
clean:
rm mutatee mutator mutated
mutatee: mutatee.cpp
$(CPP) -g -o mutatee mutatee.cpp
mutator: mutator.cpp
$(CPP) -g -o mutator $(INCLUDE) $(LINK) $(LINK2) mutator.cpp

View File

@ -0,0 +1,6 @@
DYNINSTAPI_RT_LIB=/opt/rh/devtoolset-3/root/usr/lib64/dyninst/libdyninstAPI_RT.so
export DYNINSTAPI_RT_LIB
if [[ ! $LD_LIBRARY_PATH =~ .*dyninst.* ]]; then
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/dyninst
fi
export LD_LIBRARY_PATH

View File

@ -0,0 +1,32 @@
#include <cstdio>
#include <unistd.h>
#include <cstdlib>
#include <iostream>
using namespace std;
int a = 0;
void incr(void)
{
a++;
}
int function_name(void)
{
int i;
sleep(3);
if(a)
printf("MUTATION OK.\n");
else
printf("MUTATION FAILED.\n");
return a;
}
int main(int argc, char **argv)
{
function_name();
}

View File

@ -0,0 +1,69 @@
#include <cstdlib>
#include <cstdio>
#include <string>
#include <vector>
#include <iostream>
// dyninst libraries
#include "BPatch.h"
#include "BPatch_addressSpace.h"
#include "BPatch_process.h"
#include "BPatch_function.h"
#include "BPatch_point.h"
//#include "BPatch_flowGraph.h"
using namespace std;
BPatch bpatch;
int main(int argc, char **argv)
{
int pid;
BPatch_binaryEdit *app_bin;
BPatch_addressSpace *aspace;
BPatch_image *image;
/* // check the options
if(argc != 2)
{
cerr << "ERROR ## Missing command line args. Use PID of the process you want to attach.\n";
return 1;
}
pid = atoi(argv[1]);
if(pid == 0)
{
cerr << "ERROR ## Wrong PID " << pid << ", please use another.\n";
return 2;
}
*/
// let's go...
app_bin = bpatch.openBinary("mutatee");
aspace = app_bin;
image = aspace->getImage();
/* BPatch_Set<BPatch_opCode> access_types;
access_types.insert(BPatch_opLoad);
access_types.insert(BPatch_opStore);
*/
vector<BPatch_function *> functions, incr_functions;
vector<BPatch_point *> *points;
image->findFunction("function_name", functions);
points = functions[0]->findPoint(BPatch_entry);
// create snippet
image->findFunction("incr", incr_functions);
vector<BPatch_snippet *> incr_args;
BPatch_funcCallExpr incr_call(*(incr_functions[0]), incr_args);
aspace->insertSnippet(incr_call, *points);
app_bin->writeFile("mutated");
cout << "MUTATION DONE. MUTATOR IS GOING...\n";
return 0;
}