Skip to content

Commit

Permalink
e2e: fuzz topology-aware
Browse files Browse the repository at this point in the history
  • Loading branch information
askervin committed Feb 12, 2021
1 parent 9cff111 commit 0607ee9
Show file tree
Hide file tree
Showing 8 changed files with 23,194 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
source $TEST_DIR/codelib.sh || {
echo "error importing lib.sh"
exit 1
}

( kubectl delete pods rgu0 rbu0 rbe0 -n kube-system --now ) || true

gencodes=0
for genscript in "$TEST_DIR"/generated*.sh; do
if [ ! -f "$genscript" ]; then
continue
fi
(
paralleloutdir="$outdir/parallel$gencodes"
[ -d "$paralleloutdir" ] && rm -rf "$paralleloutdir"
mkdir "$paralleloutdir"
OUTPUT_DIR="$paralleloutdir"
COMMAND_OUTPUT_DIR="$paralleloutdir/commands"
mkdir "$COMMAND_OUTPUT_DIR"
source "$genscript" 2>&1 | sed -u -e "s/^/$(basename "$genscript"): /g"
) &
gencodes=$(( gencodes + 1))
done

if [[ "$gencodes" == "0" ]]; then
echo "Test verdict: SKIP (no generated fuzz tests)"
exit 0
fi

echo "============================================"
echo "============================================"
echo "============================================"
echo "============================================"
echo "waiting..."

wait
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
container-exit0() {
# Terminate a container by killing the "sleep inf" child process in
# echo CONTNAME $(sleep inf)
local contname="$1"
vm-command "contpid=\$(ps axf | grep -A1 'echo $contname' | grep -v grep | awk '/_ sleep inf/{print \$1}'); kill -KILL \$contpid"
}

container-signal() {
local contname="$1"
local signal="$2"
vm-command "pkill -$signal -f 'echo $contname'"
}
151 changes: 151 additions & 0 deletions test/e2e/policies.test-suite/topology-aware/n4c16/test06-fuzz/fuzz.aal
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
language python {
max_mem=8000 # maximum memory on VM in MB
max_cpu=15000 # maximum CPUs on node in mCPU
max_reserved_cpu=1000 # maximum reserved CPUs on node in mCPU
class Vars:
# namespace for variables in input names
def __repr__(self):
return "{" + ",".join("%s:%s" % (a, getattr(self, a)) for a in sorted(self.__dict__.keys()) if not a.startswith("_")) + "}\n"
def inputvars(input_name):
# parse VAR=VALUE's from input_name
v = Vars()
for word in input_name.split():
keyvalue = word.split("=")
if len(keyvalue) == 2:
if (keyvalue[1].endswith("m") or keyvalue[1].endswith("M")) and len(keyvalue[1]) > 1 and keyvalue[1][-2] in '0123456789':
keyvalue[1] = keyvalue[1][:-1]
try:
setattr(v, keyvalue[0], int(keyvalue[1]))
except:
setattr(v, keyvalue[0], keyvalue[1])
return v
}

variables {
mem, cpu, reserved_cpu, pods
}

initial_state {
mem=0
cpu=0
reserved_cpu=0
pods={}
}

# Create non-reserved CPU pods
# On this topology, there is
# - 2G mem/numanode, 4G mem/package, 8G mem in total
# - 4 CPU/numanode, 8 CPU/package, 16 CPU in total
input
"NAME=gu0 CONTCOUNT=1 CPU=200m MEM=1500M create guaranteed",
"NAME=gu1 CONTCOUNT=2 CPU=1000m MEM=500M create guaranteed",
"NAME=gu2 CONTCOUNT=2 CPU=1200m MEM=4500M create guaranteed",
"NAME=gu3 CONTCOUNT=3 CPU=2000m MEM=500M create guaranteed",
"NAME=gu4 CONTCOUNT=1 CPU=4200m MEM=100M create guaranteed",
"NAME=bu0 CONTCOUNT=1 CPU=900m MEM=50M CPUREQ=900m MEMREQ=50M CPULIM=1200m MEMLIM=100M create burstable",
"NAME=bu1 CONTCOUNT=2 CPU=1900m MEM=50M CPUREQ=1900m MEMREQ=50M CPULIM=4000m MEMLIM=1000M create burstable",
"NAME=be0 CONTCOUNT=1 CPU=0 MEM=0 create besteffort",
"NAME=be1 CONTCOUNT=3 CPU=0 MEM=0 create besteffort"
{
guard {
v = inputvars(input_name)
return (v.NAME not in pods
and (mem + v.MEM * v.CONTCOUNT < max_mem)
and (cpu + v.CPU * v.CONTCOUNT < max_cpu))
}
body {
v = inputvars(input_name)
v.namespace = getattr(v, "namespace", "default")
mem += v.MEM * v.CONTCOUNT
cpu += v.CPU * v.CONTCOUNT
pods[v.NAME] = v
}
}

# Create pods to the kube-system namespace
input
"NAME=rgu0 CONTCOUNT=2 CPU=200m MEM=1000M namespace=kube-system create guaranteed",
"NAME=rbu0 CONTCOUNT=1 CPU=200m MEM=100M CPUREQ=200m MEMREQ=100M CPULIM=2500m MEMLIM=2500M namespace=kube-system create burstable",
"NAME=rbe0 CONTCOUNT=2 CPU=0 MEM=0 namespace=kube-system create besteffort"
{
guard {
v = inputvars(input_name)
return (v.NAME not in pods
and (mem + v.MEM * v.CONTCOUNT < max_mem)
and (cpu + v.CPU * v.CONTCOUNT < max_reserved_cpu))

}
body {
v = inputvars(input_name)
mem += v.MEM * v.CONTCOUNT
reserved_cpu += v.CPU * v.CONTCOUNT
pods[v.NAME] = v
}
}

# Kill a process in a container
# - "echo gu0c1" matches and kills process only in container gu0c1 in pod gu0
# - "echo gu0" matches and kills processes in all containers of pod gu0
input
"NAME=gu0 container-exit0 gu0c0",
"NAME=gu1 container-exit0 gu1c0",
"NAME=gu2 container-exit0 gu2c0",
"NAME=gu3 container-exit0 gu3",
"NAME=gu4 container-exit0 gu4c",
"NAME=bu0 container-exit0 bu0c0",
"NAME=bu1 container-exit0 bu1c0",
"NAME=be0 container-exit0 be0c0",
"NAME=be1 container-exit0 be0c0",
"NAME=rgu0 container-exit0 rgu0c0",
"NAME=rbu0 container-exit0 rbu0c0",
"NAME=rbe0 container-exit0 rbe0c0"
{
guard {
v = inputvars(input_name)
return v.NAME in pods
}
}

# Delete single pod
input
"NAME=gu0 kubectl delete pod gu0 --now",
"NAME=gu1 kubectl delete pod gu1 --now",
"NAME=gu2 kubectl delete pod gu2 --now",
"NAME=gu3 kubectl delete pod gu3 --now",
"NAME=gu4 kubectl delete pod gu4 --now",
"NAME=bu0 kubectl delete pod bu0 --now",
"NAME=bu1 kubectl delete pod bu1 --now",
"NAME=be0 kubectl delete pod be0 --now",
"NAME=be1 kubectl delete pod be1 --now",
"NAME=rgu0 kubectl delete pod rgu0 -n kube-system --now",
"NAME=rbu0 kubectl delete pod rbu0 -n kube-system --now",
"NAME=rbe0 kubectl delete pod rbe0 -n kube-system --now"
{
guard {
v = inputvars(input_name)
return v.NAME in pods
}
body {
v = inputvars(input_name)
p = pods[v.NAME]
mem -= p.MEM * p.CONTCOUNT
if getattr(p, "namespace", "") == "kube-system":
reserved_cpu -= p.CPU * p.CONTCOUNT
else:
cpu -= p.CPU * p.CONTCOUNT
del pods[v.NAME]
}
}

input "( kubectl delete pods rgu0 rbu0 rbe0 -n kube-system --now ) ; ( kubectl delete pods gu0 gu1 gu2 gu3 gu4 bu0 bu1 be0 be1 --now )"
{
guard {
return len(pods) > 0
}
body {
mem=0
cpu=0
reserved_cpu=0
pods={}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
model = aal_remote(remote_pyaal --verbose-fmbt-log fuzz.aal)
heuristic = mrandom(80,lookahead(1:2),20,random)
coverage = perm(2)

pass = coverage(10)
pass = steps(100)
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash

usage() {
cat <<EOF
generate.sh - generate fuzz tests.
Configuring test generation with environment variables:
TESTCOUNT=<NUM> Number of generated test scripts than run in parallel.
MEM=<NUM> Memory [MB] available for all pods in the system.
CPU=<NUM> Non-reserved CPU [mCPU] available for all pods in the system.
RESERVED_CPU=<NUM> Reserved CPU [mCPU] available for all pods in the system.
STEPS=<NUM> Total number of test steps in all parallel tests.
EOF
exit 0
}

if [ -n "$1" ]; then
usage
fi

TESTCOUNT=${TESTCOUNT:-1}
MEM=${MEM:-8000}
CPU=${CPU:-15000}
RESERVED_CPU=${RESERVED_CPU:-1000}
STEPS=${STEPS:-100}

mem_per_test=$(( MEM / TESTCOUNT ))
cpu_per_test=$(( CPU / TESTCOUNT ))
reserved_cpu_per_test=$(( RESERVED_CPU / TESTCOUNT ))
steps_per_test=$(( STEPS / TESTCOUNT ))

cd "$(dirname "$0")" || {
echo "cannot cd to the directory of $0"
exit 1
}

for testnum in $(seq 1 "$TESTCOUNT"); do
testid=$(( testnum - 1))
sed -e "s/max_mem=.*/max_mem=${mem_per_test}/" \
-e "s/max_cpu=.*/max_cpu=${cpu_per_test}/" \
-e "s/max_reserved_cpu=.*/max_reserved_cpu=${reserved_cpu_per_test}/" \
< fuzz.aal > tmp.fuzz.aal
sed -e "s/fuzz\.aal/tmp.fuzz.aal/" \
-e "s/pass = steps(.*/pass = steps(${steps_per_test})/" \
< fuzz.fmbt.conf > tmp.fuzz.fmbt.conf
OUTFILE=generated${testid}.sh
echo "generating $OUTFILE..."
docker run -v "$(pwd):/mnt/models" fmbt:latest sh -c 'cd /mnt/models; fmbt tmp.fuzz.fmbt.conf 2>/dev/null | fmbt-log -f \$as\$al' | grep -v AAL | sed -e 's/^, / /g' -e 's/^\([^i].*\)/echo "expected: \1"/g' -e 's/^i:\(.*\)/\1; kubectl get pods -A; vm-command "date +%T.%N"/g' | sed "s/\([^a-z0-9]\)\(r\?\)\(gu\|bu\|be\)\([0-9]\)/\1t${testid}\2\3\4/g" > "$OUTFILE"
done
Loading

0 comments on commit 0607ee9

Please sign in to comment.