[6.0] 2c214ad55 Make witness mode a first-class citizen
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Fri Jun 21 13:43:08 UTC 2024
commit 2c214ad5573726a73a8a6d04970ec1c65759d30f
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Mon Sep 30 08:02:20 2019 +0200
Make witness mode a first-class citizen
This change introduces a top-level make witness target that builds a dot
graph and if graphviz is available, an SVG file as well. A shell script
replaces the previous python script that no longer works. Instead of
fixing witness.py, which is probably trivial, the shell script does an
intermediate pass and programmatically looks for cycles using tsort(1).
Checking lock dependencies becomes actionable in a CI context.
The script also takes explicit test directories on purpose, to have the
ability to aggregate test results from multiple executions. For example
when the test suite is run on various operating systems or with varying
privileges to cover feature-conditional tests.
Conflicts:
tools/witness.sh
The 6.0 branch does not contain the dT change in the vtc output, so
columns collected by the shell script were off by one.
diff --git a/.gitignore b/.gitignore
index f6870aa1b..2bac013d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -139,6 +139,10 @@ cscope.*out
/cov-int
/myproject.tgz
+# Witness droppings
+witness.dot
+witness.svg
+
# Flexelint droppings
_.fl
_.fl.old
diff --git a/Makefile.am b/Makefile.am
index f019082a2..781d413ce 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,7 +8,13 @@ pkgconfig_DATA = varnishapi.pc
m4dir = $(datadir)/aclocal
m4_DATA = varnish.m4 varnish-legacy.m4
-CLEANFILES = cscope.in.out cscope.out cscope.po.out
+CLEANFILES = \
+ cscope.in.out \
+ cscope.out \
+ cscope.po.out \
+ witness.dot \
+ witness.svg
+
EXTRA_DIST = \
README.rst \
README.Packaging \
@@ -48,4 +54,24 @@ cscope:
gcov_digest:
${PYTHON} tools/gcov_digest.py -o _gcov
-.PHONY: cscope
+witness.dot: all
+ $(MAKE) -C bin/varnishtest check AM_VTC_LOG_FLAGS=-pdebug=+witness
+ $(AM_V_GEN) $(srcdir)/tools/witness.sh witness.dot bin/varnishtest
+
+.dot.svg:
+if ! HAVE_DOT
+ @echo ==================================================
+ @echo You need graphviz installed to generate svg output
+ @echo ==================================================
+ @false
+else
+ $(AM_V_GEN) $(DOT) -Tsvg $< >$@
+endif
+
+if HAVE_DOT
+witness: witness.svg
+else
+witness: witness.dot
+endif
+
+.PHONY: cscope witness.dot
diff --git a/bin/varnishtest/witness.py b/bin/varnishtest/witness.py
deleted file mode 100644
index f5b516ee0..000000000
--- a/bin/varnishtest/witness.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python3
-#
-# This script is in the public domain
-#
-# Run instructions:
-# varnishtest -W -iv -j <pick_a_number> > _.w
-# python witness.py
-# dot -Tpng /tmp/_.dot > /tmp/_.png
-
-d = dict()
-a = dict()
-
-fi = open("_.w")
-fo = open("/tmp/_.dot", "w")
-
-fo.write('''digraph {
- #rotate="90"
- #page="8.2,11.7"
- size="8.2,11.7"
- rankdir="LR"
- node [fontname="Inconsolata", fontsize="10"]
- edge [fontname="Inconsolata", fontsize="10"]
-''')
-
-for i in fi:
- l = "ROOT"
- j = i.split()
- if len(j) < 8:
- continue
- if j[1][0] != 'v':
- continue
- if j[3] != "vsl|":
- continue
- if j[5] != "Witness":
- continue
- t = j[7:]
- tt = str(t)
- if tt in d:
- continue
- d[tt] = True
- for e in t:
- f = e.split(",")
- x = '"%s" -> "%s" [label="%s(%s)"]\n' % (l, f[0], f[1], f[2])
- if not x in a:
- a[x] = True
- fo.write(x)
- l = f[0]
-
-fo.write("}\n")
-
diff --git a/tools/witness.sh b/tools/witness.sh
new file mode 100755
index 000000000..814fae4a0
--- /dev/null
+++ b/tools/witness.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+set -e
+set -u
+
+readonly work_dir=$(mktemp -d)
+trap 'rm -rf "$work_dir"' EXIT
+
+witness_full_paths() {
+ find "$@" -name '*.log' -print0 |
+ xargs -0 awk '$4 == "vsl|" && $6 == "Witness" {
+ printf "%s", "ROOT"
+ for (i = 8; i <= NF; i++) {
+ printf " %s", $i
+ }
+ printf "\n"
+ }' |
+ sort |
+ uniq
+}
+
+witness_edges() {
+ awk '{
+ for (i = 1; i < NF; i++) {
+ printf "%s %s\n", $i, $(i + 1)
+ }
+ }' |
+ sort |
+ uniq
+}
+
+witness_cycles() {
+ ! awk -F '[ ,]' '{print $1 " " $(NF - 2)}' |
+ tsort >/dev/null 2>&1
+}
+
+witness_graph() {
+ cat <<-EOF
+ digraph {
+ size="8.2,11.7"
+ rankdir="LR"
+ node [fontname="Inconsolata", fontsize="10"]
+ edge [fontname="Inconsolata", fontsize="10"]
+ EOF
+
+ awk -F '[ ,]' '{
+ printf " \"%s\" -> \"%s\" [label=\"%s(%s)\"]\n",
+ $1, $(NF - 2), $(NF - 1), $NF
+ }' |
+ sort |
+ uniq
+
+ echo '}'
+}
+
+if [ $# -lt 2 ]
+then
+ cat >&2 <<-EOF
+ usage: $0 dot_file test_dirs...
+ EOF
+ exit 1
+fi
+
+dest_file=$1
+shift
+
+witness_full_paths "$@" |
+witness_edges >"$work_dir/witness-edges.txt"
+
+tsort_err=
+
+if witness_cycles <"$work_dir/witness-edges.txt"
+then
+ echo "Error: lock cycle witnessed" >&2
+ tsort_err=1
+fi
+
+witness_graph <"$work_dir/witness-edges.txt" >"$work_dir/witness.dot"
+
+mv "$work_dir/witness.dot" "$dest_file"
+
+exit $tsort_err
More information about the varnish-commit
mailing list