author | Alberto Bertogli
<albertito@blitiri.com.ar> 2023-02-01 22:05:39 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2023-02-01 22:05:39 UTC |
parent | f61e48160f7ce2658e813217d65584dd1c0aa9f8 |
coverage_test.go | +0 | -39 |
dnss.go | +17 | -0 |
tests/coverage.sh | +12 | -10 |
tests/external.sh | +3 | -11 |
tests/gocovcat.go | +0 | -91 |
diff --git a/coverage_test.go b/coverage_test.go deleted file mode 100644 index 1ca53b4..0000000 --- a/coverage_test.go +++ /dev/null @@ -1,39 +0,0 @@ -// Test file used to build a coverage-enabled binary. -// -// Go lacks support for properly building a coverage binary, it can only build -// coverage test binaries. As a workaround, we have a test that just runs -// main. We then build a binary of this test, which we use instead of the -// normal binary in integration tests. -// -// This is hacky and horrible. -// -// The test has a build label so it's not accidentally executed during normal -// "go test" invocations. -// +build coveragebin - -package main - -import ( - "os" - "os/signal" - "syscall" - "testing" -) - -func TestRunMain(t *testing.T) { - done := make(chan bool) - - signals := make(chan os.Signal, 1) - go func() { - <-signals - done <- true - }() - signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGTERM) - - go func() { - main() - done <- true - }() - - <-done -} diff --git a/dnss.go b/dnss.go index 8f5f685..1ba2d5b 100644 --- a/dnss.go +++ b/dnss.go @@ -16,7 +16,10 @@ import ( "fmt" "net/http" "net/url" + "os" + "os/signal" "sync" + "syscall" "blitiri.com.ar/go/dnss/internal/dnsserver" "blitiri.com.ar/go/dnss/internal/httpresolver" @@ -79,6 +82,8 @@ func main() { flag.Parse() log.Init() + go signalHandler() + if *monitoringListenAddr != "" { launchMonitoringServer(*monitoringListenAddr) } @@ -143,6 +148,18 @@ func main() { wg.Wait() } +func signalHandler() { + signals := make(chan os.Signal, 1) + signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT) + + for sig := range signals { + switch sig { + case syscall.SIGTERM, syscall.SIGINT: + log.Fatalf("Got signal to exit: %v", sig) + } + } +} + func launchMonitoringServer(addr string) { log.Infof("Monitoring HTTP server listening on %s", addr) diff --git a/tests/coverage.sh b/tests/coverage.sh index 8285192..645b96c 100755 --- a/tests/coverage.sh +++ b/tests/coverage.sh @@ -11,25 +11,27 @@ cd "$(realpath `dirname ${0}`)/../" # Recreate the coverage output directory, to avoid including stale results # from previous runs. rm -rf .coverage -mkdir -p .coverage +mkdir -p .coverage/sh .coverage/go .coverage/all export COVER_DIR="$PWD/.coverage" - +# Run Go tests in coverage mode. go test \ -covermode=count \ - -coverprofile="$COVER_DIR/pkg-tests.out" \ -coverpkg=./... \ - ./... + ./... \ + -args -test.gocoverdir=${COVER_DIR}/go/ -# These will run in coverage mode due to $COVER_DIR being set. -setsid -w ./tests/external.sh +# Run external tests in coverage mode. They will run in coverage mode due to +# $GOCOVERDIR being set. +GOCOVERDIR="${COVER_DIR}/sh" setsid -w ./tests/external.sh # Merge all coverage output into a single file. -go run "tests/gocovcat.go" .coverage/*.out \ - > .coverage/all.out +go tool covdata merge -i "${COVER_DIR}/go,${COVER_DIR}/sh" -o "${COVER_DIR}/all" +go tool covdata textfmt -i "${COVER_DIR}/all" -o "${COVER_DIR}/merged.out" -go tool cover -func=.coverage/all.out | sort -k 3 -n > ".func.txt" -go tool cover -html=.coverage/all.out -o .coverage/dnss.cover.html +# Generate reports based on the merged output. +go tool cover -func=.coverage/merged.out | sort -k 3 -n > ".func.txt" +go tool cover -html=.coverage/merged.out -o .coverage/dnss.cover.html grep -i total .func.txt echo "file:///$PWD/.coverage/dnss.cover.html" diff --git a/tests/external.sh b/tests/external.sh index ba69279..fd4a9d6 100755 --- a/tests/external.sh +++ b/tests/external.sh @@ -21,9 +21,8 @@ trap "kill 0" EXIT # Kill children on exit. cd "$(realpath `dirname ${0}`)/../" # Build the dnss binary. -if [ "$COVER_DIR" != "" ]; then - go test -covermode=count -coverpkg=./... -c -tags coveragebin - mv dnss.test dnss +if [ "${GOCOVERDIR}" != "" ]; then + go build -cover -covermode=count -o dnss . else go build fi @@ -31,14 +30,7 @@ fi # Run dnss in the background (sets $PID to its process id). function dnss() { - # Set the coverage arguments each time, as we don't want the different - # runs to override the generated profile. - if [ "$COVER_DIR" != "" ]; then - COVER_ARGS="-test.run=^TestRunMain$ \ - -test.coverprofile=$COVER_DIR/it-`date +%s.%N`.out" - fi - - $SYSTEMD_ACTIVATE ./dnss $COVER_ARGS \ + $SYSTEMD_ACTIVATE ./dnss \ -v 3 -monitoring_listen_addr :1900 \ "$@" > .dnss.log 2>&1 & PID=$! diff --git a/tests/gocovcat.go b/tests/gocovcat.go deleted file mode 100644 index 5b3e759..0000000 --- a/tests/gocovcat.go +++ /dev/null @@ -1,91 +0,0 @@ -//usr/bin/env go run "$0" "$@"; exit $? -// -// From: https://git.lukeshu.com/go/cmd/gocovcat/ -// -// +build ignore - -// Copyright 2017 Luke Shumaker <lukeshu@parabola.nu> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -// Command gocovcat combines multiple go cover runs, and prints the -// result on stdout. -package main - -import ( - "bufio" - "fmt" - "os" - "sort" - "strconv" - "strings" -) - -func handleErr(err error) { - if err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - os.Exit(1) - } -} - -func main() { - modeBool := false - blocks := map[string]int{} - for _, filename := range os.Args[1:] { - file, err := os.Open(filename) - handleErr(err) - buf := bufio.NewScanner(file) - for buf.Scan() { - line := buf.Text() - - if strings.HasPrefix(line, "mode: ") { - m := strings.TrimPrefix(line, "mode: ") - switch m { - case "set": - modeBool = true - case "count", "atomic": - // do nothing - default: - fmt.Fprintf(os.Stderr, "Unrecognized mode: %s\n", m) - os.Exit(1) - } - } else { - sp := strings.LastIndexByte(line, ' ') - block := line[:sp] - cntStr := line[sp+1:] - cnt, err := strconv.Atoi(cntStr) - handleErr(err) - blocks[block] += cnt - } - } - handleErr(buf.Err()) - } - keys := make([]string, 0, len(blocks)) - for key := range blocks { - keys = append(keys, key) - } - sort.Strings(keys) - modeStr := "count" - if modeBool { - modeStr = "set" - } - fmt.Printf("mode: %s\n", modeStr) - for _, block := range keys { - cnt := blocks[block] - if modeBool && cnt > 1 { - cnt = 1 - } - fmt.Printf("%s %d\n", block, cnt) - } -}