summaryrefslogtreecommitdiffstats
path: root/tests/shell
diff options
context:
space:
mode:
Diffstat (limited to 'tests/shell')
-rwxr-xr-xtests/shell/testcases/sets/0044interval_overlap_0136
1 files changed, 117 insertions, 19 deletions
diff --git a/tests/shell/testcases/sets/0044interval_overlap_0 b/tests/shell/testcases/sets/0044interval_overlap_0
index fad92ddc..face90f2 100755
--- a/tests/shell/testcases/sets/0044interval_overlap_0
+++ b/tests/shell/testcases/sets/0044interval_overlap_0
@@ -7,6 +7,20 @@
# existing one
# - for concatenated ranges, the new element is less specific than any existing
# overlapping element, as elements are evaluated in order of insertion
+#
+# Then, repeat the test with a set configured with a timeout, checking that:
+# - we can insert all the elements as described above
+# - once the timeout has expired, we can insert all the elements again, and old
+# elements are not present
+# - before the timeout expires again, we can re-add elements that are not
+# expected to fail, but old elements might be present
+#
+# If $NFT points to a libtool wrapper, and we're running on a slow machine or
+# kernel (e.g. KASan enabled), it might not be possible to execute hundreds of
+# commands within an otherwise reasonable 1 second timeout. Estimate a usable
+# timeout first, by counting commands and measuring against one nft rule timeout
+# itself, so that we can keep this fast for a binary $NFT on a reasonably fast
+# kernel.
# Accept Interval List
intervals_simple="
@@ -32,35 +46,119 @@ intervals_concat="
y 0-2 . 0-3 0-2 . 0-3
n 0-1 . 0-2 0-2 . 0-3
y 10-20 . 30-40 0-2 . 0-3, 10-20 . 30-40
- n 15-20 . 50-60 0-2 . 0-3, 10-20 . 30-40, 15-20 . 50-60
+ y 15-20 . 50-60 0-2 . 0-3, 10-20 . 30-40, 15-20 . 50-60
y 3-9 . 4-29 0-2 . 0-3, 10-20 . 30-40, 15-20 . 50-60, 3-9 . 4-29
y 3-9 . 4-29 0-2 . 0-3, 10-20 . 30-40, 15-20 . 50-60, 3-9 . 4-29
n 11-19 . 30-40 0-2 . 0-3, 10-20 . 30-40, 15-20 . 50-60, 3-9 . 4-29
y 15-20 . 49-61 0-2 . 0-3, 10-20 . 30-40, 15-20 . 50-60, 3-9 . 4-29, 15-20 . 49-61
"
-$NFT add table t
-$NFT add set t s '{ type inet_service ; flags interval ; }'
-$NFT add set t c '{ type inet_service . inet_service ; flags interval ; }'
+count_elements() {
+ pass=
+ interval=
+ elements=0
+ for t in ${intervals_simple} ${intervals_concat}; do
+ [ -z "${pass}" ] && pass="${t}" && continue
+ [ -z "${interval}" ] && interval="${t}" && continue
+ unset IFS
+
+ elements=$((elements + 1))
-IFS='
+ IFS='
'
-set="s"
-for t in ${intervals_simple} switch ${intervals_concat}; do
- [ "${t}" = "switch" ] && set="c" && continue
- [ -z "${pass}" ] && pass="${t}" && continue
- [ -z "${interval}" ] && interval="${t}" && continue
-
- if [ "${pass}" = "y" ]; then
- $NFT add element t ${set} "{ ${interval} }"
- else
- ! $NFT add element t ${set} "{ ${interval} }" 2>/dev/null
+ done
+ unset IFS
+}
+
+match_elements() {
+ skip=0
+ n=0
+ out=
+ for a in $($NFT list set t ${1})}; do
+ [ ${n} -eq 0 ] && { [ "${a}" = "elements" ] && n=1; continue; }
+ [ ${n} -eq 1 ] && { [ "${a}" = "=" ] && n=2; continue; }
+ [ ${n} -eq 2 ] && { [ "${a}" = "{" ] && n=3; continue; }
+
+ [ "${a}" = "}" ] && break
+
+ [ ${skip} -eq 1 ] && skip=0 && out="${out}," && continue
+ [ "${a}" = "expires" ] && skip=1 && continue
+
+ [ -n "${out}" ] && out="${out} ${a}" || out="${a}"
+
+ done
+
+ if [ "${out%,}" != "${2}" ]; then
+ echo "Expected: ${2}, got: ${out%,}"
+ return 1
fi
- $NFT list set t ${set} | tr -d '\n\t' | tr -s ' ' | \
- grep -q "elements = { ${t} }"
+}
+
+estimate_timeout() {
+ count_elements
+ $NFT add table t
+ $NFT add set t s '{ type inet_service ; flags timeout; timeout 1s; gc-interval 1s; }'
+ execs_1s=1
+ $NFT add element t s "{ 0 }"
+ while match_elements s "0" >/dev/null; do
+ execs_1s=$((execs_1s + 1))
+ done
+
+ timeout="$((elements / execs_1s * 3 / 2 + 1))"
+}
+
+add_elements() {
+ set="s"
pass=
interval=
-done
+ IFS='
+'
+ for t in ${intervals_simple} switch ${intervals_concat}; do
+ [ "${t}" = "switch" ] && set="c" && continue
+ [ -z "${pass}" ] && pass="${t}" && continue
+ [ -z "${interval}" ] && interval="${t}" && continue
+ unset IFS
+
+ if [ "${pass}" = "y" ]; then
+ if ! $NFT add element t ${set} "{ ${interval} }"; then
+ echo "Failed to insert ${interval} given:"
+ $NFT list ruleset
+ exit 1
+ fi
+ else
+ if $NFT add element t ${set} "{ ${interval} }" 2>/dev/null; then
+ echo "Could insert ${interval} given:"
+ $NFT list ruleset
+ exit 1
+ fi
+ fi
+
+ [ "${1}" != "nomatch" ] && match_elements "${set}" "${t}"
+
+ pass=
+ interval=
+ IFS='
+'
+ done
+ unset IFS
+}
+
+$NFT add table t
+$NFT add set t s '{ type inet_service ; flags interval ; }'
+$NFT add set t c '{ type inet_service . inet_service ; flags interval ; }'
+add_elements
+
+$NFT flush ruleset
+estimate_timeout
+
+$NFT flush ruleset
+$NFT add table t
+$NFT add set t s "{ type inet_service ; flags interval,timeout; timeout ${timeout}s; gc-interval ${timeout}s; }"
+$NFT add set t c "{ type inet_service . inet_service ; flags interval,timeout ; timeout ${timeout}s; gc-interval ${timeout}s; }"
+add_elements
+
+sleep $((timeout * 3 / 2))
+add_elements
-unset IFS
+add_elements nomatch