Skip to content

Commit

Permalink
Add tests for metrics.
Browse files Browse the repository at this point in the history
  • Loading branch information
sbruens committed Mar 15, 2024
1 parent 7f3d9d0 commit fb7bc2e
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 1 deletion.
4 changes: 3 additions & 1 deletion cmd/outline-ss-server/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const (
activeIPKeyTrackerReportingInterval = 5 * time.Second
)

var since = time.Since

type outlineMetrics struct {
ipinfo.IPInfoMap
activeIPKeyTracker
Expand Down Expand Up @@ -93,7 +95,7 @@ func (t *activeIPKeyTracker) reportAll() {

// Reports time connected for a given active client.
func (t *activeIPKeyTracker) reportDuration(c activeClient) {
connDuration := time.Since(c.startTime)
connDuration := since(c.startTime)
logger.Debugf("Reporting activity for key `%v`, duration: %v", c.IPKey.accessKey, connDuration)
t.metricsCallback(c.IPKey, connDuration)

Expand Down
76 changes: 76 additions & 0 deletions cmd/outline-ss-server/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
package main

import (
"strings"
"testing"
"time"

"github.com/Jigsaw-Code/outline-ss-server/ipinfo"
"github.com/Jigsaw-Code/outline-ss-server/service/metrics"
"github.com/prometheus/client_golang/prometheus"
promtest "github.com/prometheus/client_golang/prometheus/testutil"
"github.com/stretchr/testify/require"
)

Expand All @@ -40,6 +42,7 @@ func TestMethodsDontPanic(t *testing.T) {
ssMetrics.SetBuildInfo("0.0.0-test")
ssMetrics.SetNumAccessKeys(20, 2)
ssMetrics.AddOpenTCPConnection(fakeAddr("127.0.0.1:9"))
ssMetrics.AddAuthenticatedTCPConnection(fakeAddr("127.0.0.1:9"), "key-1")
ssMetrics.AddClosedTCPConnection(fakeAddr("127.0.0.1:9"), "1", "OK", proxyMetrics, 10*time.Millisecond)
ssMetrics.AddUDPPacketFromClient(ipinfo.IPInfo{CountryCode: "US", ASN: 100}, "2", "OK", 10, 20)
ssMetrics.AddUDPPacketFromTarget(ipinfo.IPInfo{CountryCode: "US", ASN: 100}, "3", "OK", 10, 20)
Expand All @@ -55,6 +58,79 @@ func TestASNLabel(t *testing.T) {
require.Equal(t, "100", asnLabel(100))
}

func TestIPKeyActivityPerKeyDoesNotReportUnlessAllConnectionsClosed(t *testing.T) {
since = func(time.Time) time.Duration { return 3 * time.Second }
reg := prometheus.NewPedanticRegistry()
ssMetrics := newPrometheusOutlineMetrics(nil, reg)
accessKey := "key-1"
status := "OK"
data := metrics.ProxyMetrics{}
duration := time.Minute

ssMetrics.AddAuthenticatedTCPConnection(fakeAddr("127.0.0.1:9"), accessKey)
ssMetrics.AddAuthenticatedTCPConnection(fakeAddr("127.0.0.1:1"), accessKey)
ssMetrics.AddClosedTCPConnection(fakeAddr("127.0.0.1:9"), accessKey, status, data, duration)

err := promtest.GatherAndCompare(
reg,
strings.NewReader(""),
"shadowsocks_ip_key_connectivity_seconds",
)
require.NoError(t, err, "unexpectedly found metric value")
}

func TestIPKeyActivityPerKey(t *testing.T) {
since = func(time.Time) time.Duration { return 3 * time.Second }
reg := prometheus.NewPedanticRegistry()
ssMetrics := newPrometheusOutlineMetrics(nil, reg)
accessKey := "key-1"
status := "OK"
data := metrics.ProxyMetrics{}
duration := time.Minute

ssMetrics.AddAuthenticatedTCPConnection(fakeAddr("127.0.0.1:9"), accessKey)
ssMetrics.AddAuthenticatedTCPConnection(fakeAddr("127.0.0.1:1"), accessKey)
ssMetrics.AddClosedTCPConnection(fakeAddr("127.0.0.1:9"), accessKey, status, data, duration)
ssMetrics.AddClosedTCPConnection(fakeAddr("127.0.0.1:1"), accessKey, status, data, duration)

expected := strings.NewReader(`
# HELP shadowsocks_ip_key_connectivity_seconds Time at least 1 connection was open for a (IP, access key) pair, per key
# TYPE shadowsocks_ip_key_connectivity_seconds counter
shadowsocks_ip_key_connectivity_seconds{access_key="key-1"} 3
`)
err := promtest.GatherAndCompare(
reg,
expected,
"shadowsocks_ip_key_connectivity_seconds",
)
require.NoError(t, err, "unexpected metric value found")
}

func TestIPKeyActivityPerLocation(t *testing.T) {
since = func(time.Time) time.Duration { return 5 * time.Second }
reg := prometheus.NewPedanticRegistry()
ssMetrics := newPrometheusOutlineMetrics(nil, reg)
accessKey := "key-1"
status := "OK"
data := metrics.ProxyMetrics{}
duration := time.Minute

ssMetrics.AddAuthenticatedTCPConnection(fakeAddr("127.0.0.1:9"), accessKey)
ssMetrics.AddClosedTCPConnection(fakeAddr("127.0.0.1:9"), accessKey, status, data, duration)

expected := strings.NewReader(`
# HELP shadowsocks_ip_key_connectivity_seconds_per_location Time at least 1 connection was open for a (IP, access key) pair, per location
# TYPE shadowsocks_ip_key_connectivity_seconds_per_location counter
shadowsocks_ip_key_connectivity_seconds_per_location{asn="",location=""} 5
`)
err := promtest.GatherAndCompare(
reg,
expected,
"shadowsocks_ip_key_connectivity_seconds_per_location",
)
require.NoError(t, err, "unexpected metric value found")
}

func BenchmarkOpenTCP(b *testing.B) {
ssMetrics := newPrometheusOutlineMetrics(nil, prometheus.NewRegistry())
b.ResetTimer()
Expand Down

0 comments on commit fb7bc2e

Please sign in to comment.