[master] 7e3e7f904 Make witness mode a first-class citizen
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Wed Oct 30 14:54:06 UTC 2019
commit 7e3e7f9040ce9527332d928967fc34f8dfcc2843
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.
diff --git a/.gitignore b/.gitignore
index 07e77ffa9..f2b991fc5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -144,6 +144,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 add21a8ca..c2cbd1c13 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 \
@@ -52,4 +58,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..9b8d0bfaa
--- /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 '$3 == "vsl|" && $5 == "Witness" {
+ printf "%s", "ROOT"
+ for (i = 7; 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