Files
nip/integration_metrics_test.go
Brian Cunnie a17e9cc8c0 🐞 Make metrics more readable (no Unicode)
When using dig to determine the metrics of my servers, e.g. "dig txt
metrics.status.sslip.io @ns-ovh.sslip.io +short", one record looks
particularly heinous:

```
"Answer \226\137\165 1: 67974722 (651.9/s)"
```

It's supposed to look like this:

```
"Answer ≥ 1: 67974722 (651.9/s)"
```

`dig` doesn't handle Unicode well. So I'm replacing "Answer ≥ 1" with
"Answer > 0". No Unicode.

It was a worthy effort, but ultimately failed.
2024-12-04 18:16:17 -08:00

239 lines
10 KiB
Go

package main_test
import (
"fmt"
"os/exec"
"strconv"
"strings"
"time"
"xip/xip"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
)
var _ = Describe("IntegrationMetrics", func() {
When("the server is queried", func() {
// One big `It()` block because these tests cannot be run in parallel (singleton)
It("should update metrics", func() {
var actualMetrics xip.Metrics
expectedMetrics := getMetrics(port)
// A updates .Queries, UDPQueries .AnsweredQueries, .AnsweredAQueries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics.AnsweredAQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost 127.0.0.1.sslip.io +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// A updates .Queries, TCPQueries .AnsweredQueries, .AnsweredAQueries
expectedMetrics.Queries++
expectedMetrics.TCPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics.AnsweredAQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
// "+vc" runs the lookup over TCP, not UDP
actualMetrics = digAndGetMetrics("@localhost 127.0.0.1.sslip.io +short +vc -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// A (non-existent) record updates .Queries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost non-existent.sslip.io +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// A blocked updates .Queries, .AnsweredQueries, .AnsweredBlockedQueries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics.AnsweredBlockedQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
dig("@localhost bank-of-raiffeisen.127.0.0.1.sslip.io +short -p " + strconv.Itoa(port))
actualMetrics = getMetrics(port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// AAAA updates .Queries, .AnsweredQueries, .AnsweredAAAAQueries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics.AnsweredAAAAQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost 2600--.sslip.io aaaa +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// AAAA (non-existent) updates .Queries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost non-existent.sslip.io aaaa +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// MX (customized) updates .Queries, .AnsweredQueries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost sslip.io mx +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// MX updates .Queries, AnsweredQueries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost non-existent.sslip.io mx +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// NS updates .Queries, AnsweredQueries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost non-existent.sslip.io ns +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// NS DNS-01 challenge record updates .Queries, .AnsweredNSDNS01ChallengeQueries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
// DNS-01 challenges don't count as successful because we're not authoritative; we're delegating
expectedMetrics.AnsweredNSDNS01ChallengeQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost _acme-challenge.fe80--.sslip.io NS +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// Always successful: SOA
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
dig("@localhost non-existent.sslip.io soa +short -p " + strconv.Itoa(port))
actualMetrics = getMetrics(port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// TXT sslip.io (customized) updates .Queries, .AnsweredQueries,
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost sslip.io txt +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// TXT sslip.io (non-existent) updates .Queries, .AnsweredQueries,
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost non-existent.sslip.io txt +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// TXT ip.sslip.io updates .Queries, .AnsweredQueries, .AnsweredTXTSrcIPQueries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics.AnsweredTXTSrcIPQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost ip.sslip.io txt +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// TXT version.sslip.io updates .Queries, .AnsweredQueries, .AnsweredTXTVersionQueries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics.AnsweredTXTVersionQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost version.status.sslip.io txt +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// PTR version.sslip.io updates .Queries, .AnsweredQueries, .AnsweredPTRQueriesIPv4
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics.AnsweredPTRQueriesIPv4++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost 1.2.3.4.in-addr.arpa ptr +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// PTR version.sslip.io updates .Queries, .AnsweredQueries, .AnsweredPTRQueriesIPv6
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredQueries++
expectedMetrics.AnsweredPTRQueriesIPv6++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost 2.a.b.b.4.0.2.9.a.e.e.6.e.c.4.1.0.f.9.6.0.0.1.0.6.4.6.0.1.0.6.2.ip6.arpa ptr +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
// TXT DNS-01 challenge record updates .Queries, .AnsweredNSDNS01ChallengeQueries
expectedMetrics.Queries++
expectedMetrics.UDPQueries++
expectedMetrics.AnsweredNSDNS01ChallengeQueries++
expectedMetrics = bumpExpectedToAccountForMetricsQuery(expectedMetrics)
actualMetrics = digAndGetMetrics("@localhost _acme-challenge.fe80--.sslip.io txt +short -p "+strconv.Itoa(port), port)
Expect(expectedMetrics.MostlyEquals(actualMetrics)).To(BeTrue())
})
})
})
// bumpExpectedToAccountForMetricsQuery takes into account that
// digging for the metrics endpoint affects the metrics. It's like
// the Heisenberg uncertainty principle (observing changes the values)
func bumpExpectedToAccountForMetricsQuery(metrics xip.Metrics) xip.Metrics {
metrics.Queries++
metrics.UDPQueries++
metrics.AnsweredQueries++
return metrics
}
func digAndGetMetrics(digArgs string, port int) xip.Metrics {
dig(digArgs)
return getMetrics(port)
}
func dig(digArgs string) {
digCmd := exec.Command("dig", strings.Split(digArgs, " ")...)
digSession, err := Start(digCmd, GinkgoWriter, GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Eventually(digSession, 1).Should(Exit(0))
}
func getMetrics(port int) (m xip.Metrics) {
digArgs := "@localhost metrics.status.sslip.io txt +short -p " + strconv.Itoa(port)
digCmd := exec.Command("dig", strings.Split(digArgs, " ")...)
stdout, err := digCmd.Output()
Expect(err).ToNot(HaveOccurred())
var uptime int
var junk string
_, err = fmt.Sscanf(string(stdout),
"\"Uptime: %d\"\n"+
"\"Blocklist: %s %s %s\n"+
"\"Queries: %d (%s\n"+ // %s "swallows" the `/s"` at the end
"\"TCP/UDP: %d/%d\"\n"+
"\"Answer > 0: %d (%s\n"+ // %s "swallows" the `/s"` at the end
"\"A: %d\"\n"+
"\"AAAA: %d\"\n"+
"\"TXT Source: %d\"\n"+
"\"TXT Version: %d\"\n"+
"\"PTR IPv4/IPv6: %d/%d\"\n"+
"\"NS DNS-01: %d\"\n"+
"\"Blocked: %d\"\n",
&uptime,
&junk, &junk, &junk,
&m.Queries, &junk,
&m.TCPQueries, &m.UDPQueries,
&m.AnsweredQueries, &junk,
&m.AnsweredAQueries,
&m.AnsweredAAAAQueries,
&m.AnsweredTXTSrcIPQueries,
&m.AnsweredTXTVersionQueries,
&m.AnsweredPTRQueriesIPv4, &m.AnsweredPTRQueriesIPv6,
&m.AnsweredNSDNS01ChallengeQueries,
&m.AnsweredBlockedQueries,
)
Expect(err).ToNot(HaveOccurred())
m.Start = time.Now().Add(-time.Duration(uptime) * time.Second)
//_, err = fmt.Fscanf(digSession.Out, "queries: %d", &m.Queries)
return m
}