15
15
package main
16
16
17
17
import (
18
+ "strings"
18
19
"testing"
19
20
"time"
20
21
21
22
"github.com/Jigsaw-Code/outline-ss-server/ipinfo"
22
23
"github.com/Jigsaw-Code/outline-ss-server/service/metrics"
23
24
"github.com/prometheus/client_golang/prometheus"
25
+ promtest "github.com/prometheus/client_golang/prometheus/testutil"
24
26
"github.com/stretchr/testify/require"
25
27
)
26
28
@@ -40,6 +42,7 @@ func TestMethodsDontPanic(t *testing.T) {
40
42
ssMetrics .SetBuildInfo ("0.0.0-test" )
41
43
ssMetrics .SetNumAccessKeys (20 , 2 )
42
44
ssMetrics .AddOpenTCPConnection (fakeAddr ("127.0.0.1:9" ))
45
+ ssMetrics .AddAuthenticatedTCPConnection (fakeAddr ("127.0.0.1:9" ), "key-1" )
43
46
ssMetrics .AddClosedTCPConnection (fakeAddr ("127.0.0.1:9" ), "1" , "OK" , proxyMetrics , 10 * time .Millisecond )
44
47
ssMetrics .AddUDPPacketFromClient (ipinfo.IPInfo {CountryCode : "US" , ASN : 100 }, "2" , "OK" , 10 , 20 )
45
48
ssMetrics .AddUDPPacketFromTarget (ipinfo.IPInfo {CountryCode : "US" , ASN : 100 }, "3" , "OK" , 10 , 20 )
@@ -55,6 +58,79 @@ func TestASNLabel(t *testing.T) {
55
58
require .Equal (t , "100" , asnLabel (100 ))
56
59
}
57
60
61
+ func TestIPKeyActivityPerKeyDoesNotReportUnlessAllConnectionsClosed (t * testing.T ) {
62
+ since = func (time.Time ) time.Duration { return 3 * time .Second }
63
+ reg := prometheus .NewPedanticRegistry ()
64
+ ssMetrics := newPrometheusOutlineMetrics (nil , reg )
65
+ accessKey := "key-1"
66
+ status := "OK"
67
+ data := metrics.ProxyMetrics {}
68
+ duration := time .Minute
69
+
70
+ ssMetrics .AddAuthenticatedTCPConnection (fakeAddr ("127.0.0.1:9" ), accessKey )
71
+ ssMetrics .AddAuthenticatedTCPConnection (fakeAddr ("127.0.0.1:1" ), accessKey )
72
+ ssMetrics .AddClosedTCPConnection (fakeAddr ("127.0.0.1:9" ), accessKey , status , data , duration )
73
+
74
+ err := promtest .GatherAndCompare (
75
+ reg ,
76
+ strings .NewReader ("" ),
77
+ "shadowsocks_ip_key_connectivity_seconds" ,
78
+ )
79
+ require .NoError (t , err , "unexpectedly found metric value" )
80
+ }
81
+
82
+ func TestIPKeyActivityPerKey (t * testing.T ) {
83
+ since = func (time.Time ) time.Duration { return 3 * time .Second }
84
+ reg := prometheus .NewPedanticRegistry ()
85
+ ssMetrics := newPrometheusOutlineMetrics (nil , reg )
86
+ accessKey := "key-1"
87
+ status := "OK"
88
+ data := metrics.ProxyMetrics {}
89
+ duration := time .Minute
90
+
91
+ ssMetrics .AddAuthenticatedTCPConnection (fakeAddr ("127.0.0.1:9" ), accessKey )
92
+ ssMetrics .AddAuthenticatedTCPConnection (fakeAddr ("127.0.0.1:1" ), accessKey )
93
+ ssMetrics .AddClosedTCPConnection (fakeAddr ("127.0.0.1:9" ), accessKey , status , data , duration )
94
+ ssMetrics .AddClosedTCPConnection (fakeAddr ("127.0.0.1:1" ), accessKey , status , data , duration )
95
+
96
+ expected := strings .NewReader (`
97
+ # HELP shadowsocks_ip_key_connectivity_seconds Time at least 1 connection was open for a (IP, access key) pair, per key
98
+ # TYPE shadowsocks_ip_key_connectivity_seconds counter
99
+ shadowsocks_ip_key_connectivity_seconds{access_key="key-1"} 3
100
+ ` )
101
+ err := promtest .GatherAndCompare (
102
+ reg ,
103
+ expected ,
104
+ "shadowsocks_ip_key_connectivity_seconds" ,
105
+ )
106
+ require .NoError (t , err , "unexpected metric value found" )
107
+ }
108
+
109
+ func TestIPKeyActivityPerLocation (t * testing.T ) {
110
+ since = func (time.Time ) time.Duration { return 5 * time .Second }
111
+ reg := prometheus .NewPedanticRegistry ()
112
+ ssMetrics := newPrometheusOutlineMetrics (nil , reg )
113
+ accessKey := "key-1"
114
+ status := "OK"
115
+ data := metrics.ProxyMetrics {}
116
+ duration := time .Minute
117
+
118
+ ssMetrics .AddAuthenticatedTCPConnection (fakeAddr ("127.0.0.1:9" ), accessKey )
119
+ ssMetrics .AddClosedTCPConnection (fakeAddr ("127.0.0.1:9" ), accessKey , status , data , duration )
120
+
121
+ expected := strings .NewReader (`
122
+ # HELP shadowsocks_ip_key_connectivity_seconds_per_location Time at least 1 connection was open for a (IP, access key) pair, per location
123
+ # TYPE shadowsocks_ip_key_connectivity_seconds_per_location counter
124
+ shadowsocks_ip_key_connectivity_seconds_per_location{asn="",location=""} 5
125
+ ` )
126
+ err := promtest .GatherAndCompare (
127
+ reg ,
128
+ expected ,
129
+ "shadowsocks_ip_key_connectivity_seconds_per_location" ,
130
+ )
131
+ require .NoError (t , err , "unexpected metric value found" )
132
+ }
133
+
58
134
func BenchmarkOpenTCP (b * testing.B ) {
59
135
ssMetrics := newPrometheusOutlineMetrics (nil , prometheus .NewRegistry ())
60
136
b .ResetTimer ()
0 commit comments