mirror of
https://github.com/cunnie/sslip.io.git
synced 2025-10-07 08:31:02 +08:00

I've always been uncomfortable with the metric "Answered Queries" — it implies that we don't answer all the queries. But we do answer all the queries! What the metric meant is "the number of DNS responses that we send that have one or more records in the ANSWER section". The new metric is "Answer ≥ 1". Not great, but better than before.
240 lines
10 KiB
Go
240 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
|
|
var greaterThanOrEqualsUnicode 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 %s 1: %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,
|
|
&greaterThanOrEqualsUnicode, &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
|
|
}
|