]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
tests/dnstap: fix, refactor and integrate into meson and CI
authorVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 5 Jan 2021 15:59:48 +0000 (16:59 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Fri, 15 Jan 2021 13:52:05 +0000 (14:52 +0100)
They need one go package which I can't find even in Debian,
so it probably can't work without network access.
The new dnstap in extra_tests runs if dnstap is built and go is found.
It also tries to keep the source tree clean.

Now both query and reply messages are tested.

In CI (after caching go deps in image) this tests only takes slightly
more time than the longest config.* tests, so that seems OK.
Even so, it's not added into the valgrind variant, as compilation
of the test still isn't split away from the run itself.

.gitignore
.gitlab-ci.yml
tests/dnstap/meson.build [new file with mode: 0644]
tests/dnstap/src/dnstap-test/config
tests/dnstap/src/dnstap-test/dnstap.mk [deleted file]
tests/dnstap/src/dnstap-test/main.go
tests/dnstap/src/dnstap-test/run.sh [new file with mode: 0755]
tests/meson.build

index df30adf5c24181e2350616ba62cdc1c8cdeab70a..e28639f6e47171131d9be1afbff8b0ead3d27060 100644 (file)
 /libtool
 /ltmain.sh
 /missing
-/modules/dnstap/dnstap.pb-c.*
+/modules/dnstap/dnstap.pb-c.d
 /self.crt
 /self.key
 /stamp-h1
 /tags
-/tests/dnstap/src/dnstap-test/vendor/github.com/
-/tests/dnstap/src/github.com/
 /tests/pytests/*/tcproxy
 /tests/pytests/*/tlsproxy
 /tests/pytests/pytests.parallel.html
index 0198ce99f90507fc6b2e0eb210cc4f08449be6a8..5297f04a2eea3162182c00ae90c23ce1bfbbad12 100644 (file)
@@ -88,7 +88,7 @@ build:
     - meson build_ci --default-library=static --prefix=$PREFIX -Dwerror=true -Dextra_tests=enabled --fatal-meson-warnings
     - ninja -C build_ci
     - ninja -C build_ci install >/dev/null
-    - ${MESON_TEST} --suite unit --suite config --no-suite snowflake
+    - ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite snowflake
 
 build-asan:
   <<: *build
@@ -98,7 +98,7 @@ build-asan:
     - ninja -C build_ci_asan install >/dev/null
       # TODO _leaks: not sure what exactly is wrong in leak detection on config tests
       # TODO skip_asan: all three of these disappear locally when using gcc 9.1 (except some leaks)
-    - ASAN_OPTIONS=detect_leaks=0 ${MESON_TEST} --suite unit --suite config --no-suite skip_asan --no-suite snowflake
+    - ASAN_OPTIONS=detect_leaks=0 ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite skip_asan --no-suite snowflake
 
 build:macOS:
   <<: *nodep
diff --git a/tests/dnstap/meson.build b/tests/dnstap/meson.build
new file mode 100644 (file)
index 0000000..4d3fb10
--- /dev/null
@@ -0,0 +1,9 @@
+
+# note: it will be skipped if 'go' is missing (and marked so)
+test('dnstap',
+  find_program('./src/dnstap-test/run.sh'),
+  args: [ sbin_dir / 'kresd' ],
+  suite: [ 'postinstall', 'dnstap' ],
+  timeout: 120, # it may need to fetch go packages, etc.
+)
+
index de877f3298fc3827121e14621510b69a2de8df14..5f1530885354201ed816495182a4405366cc348d 100644 (file)
@@ -1,10 +1,10 @@
 -- SPDX-License-Identifier: GPL-3.0-or-later
-verbose(true)
 modules = {
        'hints',
        dnstap = {
-               socket_path = "/tmp/dnstap.sock",
+               socket_path = "dnstap.sock",
                client = {
+                       log_queries = true,
                        log_responses = true,
                }
        }
diff --git a/tests/dnstap/src/dnstap-test/dnstap.mk b/tests/dnstap/src/dnstap-test/dnstap.mk
deleted file mode 100644 (file)
index ab462a9..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-# dnstap tests
-GOPATH := $(abspath tests/dnstap)
-DNSTAP_TEST := dnstap-test
-DNSTAP_PATH := $(GOPATH)/src/$(DNSTAP_TEST)
-CONFIG := $(DNSTAP_PATH)/config
-CMD := daemon/kresd
-ZONES := "fake1.localdomain,fake2.localdomain,fake3.localdomain"
-TIMEOUT := 60s
-check-dnstap: daemon
-       @echo "Checking dnstap functionality"
-       GOPATH=$(GOPATH) go get -u github.com/FiloSottile/gvt
-       cd $(DNSTAP_PATH) && $(GOPATH)/bin/gvt restore
-       GOPATH=$(GOPATH) go install $(DNSTAP_TEST)
-       $(GOPATH)/bin/$(DNSTAP_TEST) -c $(CONFIG) -cmd $(CMD) -q $(ZONES) -t $(TIMEOUT)
-
-clean-dnstap:
-       rm -rf $(GOPATH)/{bin,pkg,src/dnstap-test/vendor/github.com,src/github.com}
-
-.PHONY: check-dnstap clean-dnstap
index d06879d7743b7f03ced06c8d08d633fbcccf21d0..c04b4c140a6cc5f4500a03318a2da7cacb7697a4 100644 (file)
@@ -17,14 +17,9 @@ import (
        "time"
 )
 
-const (
-       kresdWorkDir = "/tmp/"
-)
-
 var (
        kresdArgs = []string{
-               "-f1",
-               "-v",
+               "-n",
                "-q",
        }
 )
@@ -35,18 +30,25 @@ func qnameFromFrame(b []byte) (string, error) {
        if err := proto.Unmarshal(b, dt); err != nil {
                return name, err
        }
+
+       var msg_raw []byte
        m := dt.Message
-       if *m.Type != dnstap.Message_CLIENT_RESPONSE {
-               return name, fmt.Errorf("incorrect message type")
+       if *m.Type == dnstap.Message_CLIENT_QUERY {
+               msg_raw = m.QueryMessage
+       } else if *m.Type == dnstap.Message_CLIENT_RESPONSE {
+               msg_raw = m.ResponseMessage
+       } else {
+               return name, fmt.Errorf("incorrect message type: %v", *m.Type)
        }
-       if m.ResponseMessage == nil {
+
+       if msg_raw == nil {
                return name, fmt.Errorf("no message payload")
        }
-       if err := dns.IsMsg(m.ResponseMessage); err != nil {
+       if err := dns.IsMsg(msg_raw); err != nil {
                return name, err
        }
        var msg dns.Msg
-       if err := msg.Unpack(m.ResponseMessage); err != nil {
+       if err := msg.Unpack(msg_raw); err != nil {
                return name, err
        }
        if len(msg.Question) < 1 {
@@ -74,7 +76,6 @@ func listenOn() (net.Addr, *os.File, error) {
 func runKresd(ctx context.Context, path, configFile string, grace time.Duration) (chan bool, error) {
        ch := make(chan bool)
        kresdArgs = append(kresdArgs, "-c"+configFile)
-       kresdArgs = append(kresdArgs, kresdWorkDir)
        // we have 1 object in ExtraFiles with index 0
        // child fd will be 3 + i = 3
        kresdArgs = append(kresdArgs, "-S3")
@@ -144,8 +145,8 @@ func runKresd(ctx context.Context, path, configFile string, grace time.Duration)
 
 func main() {
        var (
-               unixSocket = flag.String("u", "/tmp/dnstap.sock", "dnstap socket")
-               kresdPath  = flag.String("cmd", "daemon/kresd", "kresd path")
+               unixSocket = flag.String("u", "dnstap.sock", "dnstap socket")
+               kresdPath  = flag.String("cmd", "kresd", "kresd path")
                configFile = flag.String("c", "config", "config file")
                qnames     = flag.String("q", ".", "list of comma separated zones")
                grace      = flag.String("g", "1s", "Time to wait for daemon start")
@@ -218,21 +219,22 @@ func main() {
                                log.Printf("Response: %v", resp)
                        }
 
-                       // Check dnstap output
-                       o := <-output
-                       if *debug {
-                               log.Printf("raw dnstap:%v", o)
-                       }
-                       dtName, err := qnameFromFrame(o)
-                       if err != nil {
-                               log.Printf("%v\n", err)
-                               os.Exit(1)
-                       }
-                       if fqdn != dtName {
-                               log.Printf("expected %v got %v", fqdn, dtName)
-                               os.Exit(1) // Test failed
+                       for range "QR" { // Checking Query and Response is the same ATM
+                               o := <-output
+                               if *debug {
+                                       log.Printf("raw dnstap:%v", o)
+                               }
+                               dtName, err := qnameFromFrame(o)
+                               if err != nil {
+                                       log.Printf("%v\n", err)
+                                       os.Exit(1)
+                               }
+                               if fqdn != dtName {
+                                       log.Printf("expected %v got %v", fqdn, dtName)
+                                       os.Exit(1) // Test failed
+                               }
+                               log.Printf("matched qname: %v", dtName)
                        }
-                       log.Printf("matched qname: %v", dtName)
                }
                cancel() // Send signal to close daemon
        }()
diff --git a/tests/dnstap/src/dnstap-test/run.sh b/tests/dnstap/src/dnstap-test/run.sh
new file mode 100755 (executable)
index 0000000..00f4824
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/bash
+set -e
+KRESD_CMD=$1
+MESON_BUILD_ROOT=$(pwd)
+mkdir -p tests/dnstap
+export GOPATH=$MESON_BUILD_ROOT/tests/dnstap
+cd "$(dirname $0)"
+DNSTAP_TEST=dnstap-test
+
+if [ -z "$GITLAB_CI" ]; then
+       type -P go >/dev/null || exit 77
+       echo "Building the dnstap test and its dependencies..."
+       # some packages may be missing on the system right now
+       go get github.com/{FiloSottile/gvt,cloudflare/dns,dnstap/golang-dnstap}
+else
+       # In CI we've prebuilt dependencies into the default GOPATH.
+       # We're in a scratch container, so we just add the dnstap test inside.
+       export GOPATH=/root/go
+fi
+DTAP=$GOPATH/src/$DNSTAP_TEST
+rm -f $DTAP && ln -s $(realpath ..)/$DNSTAP_TEST $DTAP
+go install $DNSTAP_TEST
+
+
+CONFIG=$(realpath ./config)
+ZONES="fake1.localdomain,fake2.localdomain,fake3.localdomain"
+TIMEOUT=60s
+GRACE=5s
+cd $MESON_BUILD_ROOT/tests/dnstap # don't leave stuff like *.mdb in ./.
+$GOPATH/bin/$DNSTAP_TEST -c $CONFIG -cmd $KRESD_CMD -q $ZONES -t $TIMEOUT -g $GRACE -d
+
index edc64947ebc90d6c4d58c96cd6f078e8c5429820..1647b30f1abedc8589cf648c3434aff6b43e9e5a 100644 (file)
@@ -47,6 +47,9 @@ if build_extra_tests
 
   subdir('pytests')
   subdir('integration')
+  if build_dnstap
+    subdir('dnstap')
+  endif
 
   foreach py3_dep : py3_deps
     py3_import = run_command(python3, '-c', 'import @0@'.format(py3_dep[0]))