riseupvpn: reduce false positives (#233)
* fetch RiseupVPN CA cert with MultiGetter. It allows us to write better tests and ensures this test step is added in the logs * Implement TransportStatus for RiseupVPN tests. It indicates if a whole transport is blocked, which is considered as a test anomaly * Redesign unit tests for RiseupVPN. Instead of a real backend, mocked server responses are used. Tests for invalid CA certs and for TransportStatus are added. * Update internal/engine/experiment/riseupvpn/riseupvpn.go Co-authored-by: Simone Basso <bassosimone@gmail.com>
This commit is contained in:
parent
dae02ce5b6
commit
991b0a6120
|
@ -9,7 +9,6 @@ import (
|
|||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/model"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx"
|
||||
|
@ -18,7 +17,7 @@ import (
|
|||
|
||||
const (
|
||||
testName = "riseupvpn"
|
||||
testVersion = "0.1.0"
|
||||
testVersion = "0.2.0"
|
||||
eipServiceURL = "https://api.black.riseup.net:443/3/config/eip-service.json"
|
||||
providerURL = "https://riseup.net/provider.json"
|
||||
geoServiceURL = "https://api.black.riseup.net:9001/json"
|
||||
|
@ -66,6 +65,7 @@ type TestKeys struct {
|
|||
APIStatus string `json:"api_status"`
|
||||
CACertStatus bool `json:"ca_cert_status"`
|
||||
FailingGateways []GatewayConnection `json:"failing_gateways"`
|
||||
TransportStatus map[string]string `json:"transport_status"`
|
||||
}
|
||||
|
||||
// NewTestKeys creates new riseupvpn TestKeys.
|
||||
|
@ -75,6 +75,7 @@ func NewTestKeys() *TestKeys {
|
|||
APIStatus: "ok",
|
||||
CACertStatus: true,
|
||||
FailingGateways: nil,
|
||||
TransportStatus: nil,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,6 +97,7 @@ func (tk *TestKeys) UpdateProviderAPITestKeys(v urlgetter.MultiOutput) {
|
|||
}
|
||||
|
||||
// AddGatewayConnectTestKeys updates the TestKeys using the given MultiOutput result of gateway connectivity testing.
|
||||
// Sets TransportStatus to "ok" if any successful TCP connection could be made
|
||||
func (tk *TestKeys) AddGatewayConnectTestKeys(v urlgetter.MultiOutput, transportType string) {
|
||||
tk.NetworkEvents = append(tk.NetworkEvents, v.TestKeys.NetworkEvents...)
|
||||
tk.TCPConnect = append(tk.TCPConnect, v.TestKeys.TCPConnect...)
|
||||
|
@ -108,6 +110,29 @@ func (tk *TestKeys) AddGatewayConnectTestKeys(v urlgetter.MultiOutput, transport
|
|||
return
|
||||
}
|
||||
|
||||
func (tk *TestKeys) updateTransportStatus(openvpnGatewayCount int, obfs4GatewayCount int) {
|
||||
failingOpenvpnGateways, failingObfs4Gateways := 0, 0
|
||||
for _, gw := range tk.FailingGateways {
|
||||
if gw.TransportType == "openvpn" {
|
||||
failingOpenvpnGateways++
|
||||
} else if gw.TransportType == "obfs4" {
|
||||
failingObfs4Gateways++
|
||||
}
|
||||
}
|
||||
|
||||
if failingOpenvpnGateways < openvpnGatewayCount {
|
||||
tk.TransportStatus["openvpn"] = "ok"
|
||||
} else {
|
||||
tk.TransportStatus["openvpn"] = "blocked"
|
||||
}
|
||||
|
||||
if failingObfs4Gateways < obfs4GatewayCount {
|
||||
tk.TransportStatus["obfs4"] = "ok"
|
||||
} else {
|
||||
tk.TransportStatus["obfs4"] = "blocked"
|
||||
}
|
||||
}
|
||||
|
||||
func newGatewayConnection(tcpConnect archival.TCPConnectEntry, transportType string) *GatewayConnection {
|
||||
return &GatewayConnection{
|
||||
IP: tcpConnect.IP,
|
||||
|
@ -160,30 +185,32 @@ func (m Measurer) Run(ctx context.Context, sess model.ExperimentSession,
|
|||
urlgetter.RegisterExtensions(measurement)
|
||||
|
||||
caTarget := "https://black.riseup.net/ca.crt"
|
||||
caGetter := urlgetter.Getter{
|
||||
Config: m.Config.Config,
|
||||
Session: sess,
|
||||
Target: caTarget,
|
||||
}
|
||||
log.Info("Getting CA certificate; please be patient...")
|
||||
tk, err := caGetter.Get(ctx)
|
||||
testkeys.AddCACertFetchTestKeys(tk)
|
||||
|
||||
if err != nil {
|
||||
log.Error("Getting CA certificate failed. Aborting test.")
|
||||
return nil
|
||||
}
|
||||
|
||||
certPool := netx.NewDefaultCertPool()
|
||||
if ok := certPool.AppendCertsFromPEM([]byte(tk.HTTPResponseBody)); !ok {
|
||||
testkeys.CACertStatus = false
|
||||
testkeys.APIStatus = "blocked"
|
||||
errorValue := "invalid_ca"
|
||||
testkeys.APIFailure = &errorValue
|
||||
return nil
|
||||
|
||||
multi := urlgetter.Multi{Begin: measurement.MeasurementStartTimeSaved, Getter: m.Getter, Session: sess}
|
||||
inputs := []urlgetter.MultiInput{
|
||||
{Target: caTarget, Config: urlgetter.Config{
|
||||
Method: "GET",
|
||||
FailOnHTTPError: true,
|
||||
}},
|
||||
}
|
||||
for entry := range multi.CollectOverall(ctx, inputs, 0, 50, "riseupvpn", callbacks) {
|
||||
tk := entry.TestKeys
|
||||
testkeys.AddCACertFetchTestKeys(tk)
|
||||
if tk.Failure != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if ok := certPool.AppendCertsFromPEM([]byte(tk.HTTPResponseBody)); !ok {
|
||||
testkeys.CACertStatus = false
|
||||
testkeys.APIStatus = "blocked"
|
||||
errorValue := "invalid_ca"
|
||||
testkeys.APIFailure = &errorValue
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
inputs := []urlgetter.MultiInput{
|
||||
inputs = []urlgetter.MultiInput{
|
||||
|
||||
// Here we need to provide the method explicitly. See
|
||||
// https://github.com/ooni/probe-engine/issues/827.
|
||||
|
@ -203,30 +230,34 @@ func (m Measurer) Run(ctx context.Context, sess model.ExperimentSession,
|
|||
FailOnHTTPError: true,
|
||||
}},
|
||||
}
|
||||
multi := urlgetter.Multi{Begin: measurement.MeasurementStartTimeSaved, Getter: m.Getter, Session: sess}
|
||||
multi = urlgetter.Multi{Begin: measurement.MeasurementStartTimeSaved, Getter: m.Getter, Session: sess}
|
||||
|
||||
for entry := range multi.CollectOverall(ctx, inputs, 0, 50, "riseupvpn", callbacks) {
|
||||
for entry := range multi.CollectOverall(ctx, inputs, 1, 50, "riseupvpn", callbacks) {
|
||||
testkeys.UpdateProviderAPITestKeys(entry)
|
||||
}
|
||||
|
||||
// test gateways now
|
||||
testkeys.TransportStatus = map[string]string{}
|
||||
gateways := parseGateways(testkeys)
|
||||
openvpnEndpoints := generateMultiInputs(gateways, "openvpn")
|
||||
obfs4Endpoints := generateMultiInputs(gateways, "obfs4")
|
||||
overallCount := len(inputs) + len(openvpnEndpoints) + len(obfs4Endpoints)
|
||||
overallCount := 1 + len(inputs) + len(openvpnEndpoints) + len(obfs4Endpoints)
|
||||
|
||||
// measure openvpn in parallel
|
||||
multi = urlgetter.Multi{Begin: measurement.MeasurementStartTimeSaved, Getter: m.Getter, Session: sess}
|
||||
for entry := range multi.CollectOverall(ctx, openvpnEndpoints, len(inputs), overallCount, "riseupvpn", callbacks) {
|
||||
for entry := range multi.CollectOverall(ctx, openvpnEndpoints, 1+len(inputs), overallCount, "riseupvpn", callbacks) {
|
||||
testkeys.AddGatewayConnectTestKeys(entry, "openvpn")
|
||||
}
|
||||
|
||||
// measure obfs4 in parallel
|
||||
multi = urlgetter.Multi{Begin: measurement.MeasurementStartTimeSaved, Getter: m.Getter, Session: sess}
|
||||
for entry := range multi.CollectOverall(ctx, obfs4Endpoints, len(inputs)+len(openvpnEndpoints), overallCount, "riseupvpn", callbacks) {
|
||||
for entry := range multi.CollectOverall(ctx, obfs4Endpoints, 1+len(inputs)+len(openvpnEndpoints), overallCount, "riseupvpn", callbacks) {
|
||||
testkeys.AddGatewayConnectTestKeys(entry, "obfs4")
|
||||
}
|
||||
|
||||
// set transport status based on gateway test results
|
||||
testkeys.updateTransportStatus(len(openvpnEndpoints), len(obfs4Endpoints))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -287,10 +318,11 @@ func NewExperimentMeasurer(config Config) model.ExperimentMeasurer {
|
|||
// Note that this structure is part of the ABI contract with probe-cli
|
||||
// therefore we should be careful when changing it.
|
||||
type SummaryKeys struct {
|
||||
APIBlocked bool `json:"api_blocked"`
|
||||
ValidCACert bool `json:"valid_ca_cert"`
|
||||
FailingGateways int `json:"failing_gateways"`
|
||||
IsAnomaly bool `json:"-"`
|
||||
APIBlocked bool `json:"api_blocked"`
|
||||
ValidCACert bool `json:"valid_ca_cert"`
|
||||
FailingGateways int `json:"failing_gateways"`
|
||||
TransportStatus map[string]string `json:"transport_status"`
|
||||
IsAnomaly bool `json:"-"`
|
||||
}
|
||||
|
||||
// GetSummaryKeys implements model.ExperimentMeasurer.GetSummaryKeys.
|
||||
|
@ -303,7 +335,8 @@ func (m Measurer) GetSummaryKeys(measurement *model.Measurement) (interface{}, e
|
|||
sk.APIBlocked = tk.APIStatus != "ok"
|
||||
sk.ValidCACert = tk.CACertStatus
|
||||
sk.FailingGateways = len(tk.FailingGateways)
|
||||
sk.TransportStatus = tk.TransportStatus
|
||||
sk.IsAnomaly = (sk.APIBlocked == true || tk.CACertStatus == false ||
|
||||
sk.FailingGateways != 0)
|
||||
tk.TransportStatus["openvpn"] == "blocked" || tk.TransportStatus["obfs4"] == "blocked")
|
||||
return sk, nil
|
||||
}
|
||||
|
|
|
@ -2,15 +2,14 @@ package riseupvpn_test
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
@ -19,36 +18,204 @@ import (
|
|||
"github.com/ooni/probe-cli/v3/internal/engine/internal/mockable"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/model"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/selfcensor"
|
||||
)
|
||||
|
||||
const (
|
||||
provider = `{
|
||||
"api_uri": "https://api.black.riseup.net:443",
|
||||
"api_version": "3",
|
||||
"ca_cert_fingerprint": "SHA256: a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494",
|
||||
"ca_cert_uri": "https://black.riseup.net/ca.crt",
|
||||
"default_language": "en",
|
||||
"description": {
|
||||
"en": "Riseup is a non-profit collective in Seattle that provides online communication tools for people and groups working toward liberatory social change."
|
||||
},
|
||||
"domain": "riseup.net",
|
||||
"enrollment_policy": "closed",
|
||||
"languages": [
|
||||
"en"
|
||||
],
|
||||
"name": {
|
||||
"en": "Riseup Networks"
|
||||
},
|
||||
"service": {
|
||||
"allow_anonymous": true,
|
||||
"allow_free": true,
|
||||
"allow_limited_bandwidth": false,
|
||||
"allow_paid": false,
|
||||
"allow_registration": false,
|
||||
"allow_unlimited_bandwidth": true,
|
||||
"bandwidth_limit": 102400,
|
||||
"default_service_level": 1,
|
||||
"levels": {
|
||||
"1": {
|
||||
"description": "Please donate.",
|
||||
"name": "free"
|
||||
}
|
||||
}
|
||||
},
|
||||
"services": [
|
||||
"openvpn"
|
||||
]
|
||||
}`
|
||||
eipservice = `{
|
||||
"gateways": [
|
||||
{
|
||||
"capabilities": {
|
||||
"adblock": false,
|
||||
"filter_dns": false,
|
||||
"limited": false,
|
||||
"transport":[
|
||||
{
|
||||
"type":"openvpn",
|
||||
"protocols":[
|
||||
"tcp"
|
||||
],
|
||||
"ports":[
|
||||
"443"
|
||||
]
|
||||
}
|
||||
],
|
||||
"user_ips": false
|
||||
},
|
||||
"host": "test1.riseup.net",
|
||||
"ip_address": "123.456.123.456",
|
||||
"location": "paris"
|
||||
},
|
||||
{
|
||||
"capabilities": {
|
||||
"adblock": false,
|
||||
"filter_dns": false,
|
||||
"limited": false,
|
||||
"transport":[
|
||||
{
|
||||
"type":"obfs4",
|
||||
"protocols":[
|
||||
"tcp"
|
||||
],
|
||||
"ports":[
|
||||
"23042"
|
||||
],
|
||||
"options": {
|
||||
"cert": "XXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||
"iatMode": "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type":"openvpn",
|
||||
"protocols":[
|
||||
"tcp"
|
||||
],
|
||||
"ports":[
|
||||
"443"
|
||||
]
|
||||
}
|
||||
],
|
||||
"user_ips": false
|
||||
},
|
||||
"host": "test2.riseup.net",
|
||||
"ip_address": "234.345.234.345",
|
||||
"location": "seattle"
|
||||
}
|
||||
],
|
||||
"locations": {
|
||||
"paris": {
|
||||
"country_code": "FR",
|
||||
"hemisphere": "N",
|
||||
"name": "Paris",
|
||||
"timezone": "+2"
|
||||
},
|
||||
"seattle": {
|
||||
"country_code": "US",
|
||||
"hemisphere": "N",
|
||||
"name": "Seattle",
|
||||
"timezone": "-7"
|
||||
}
|
||||
},
|
||||
"openvpn_configuration": {
|
||||
"auth": "SHA1",
|
||||
"cipher": "AES-128-CBC",
|
||||
"keepalive": "10 30",
|
||||
"tls-cipher": "DHE-RSA-AES128-SHA",
|
||||
"tun-ipv6": true
|
||||
},
|
||||
"serial": 3,
|
||||
"version": 3
|
||||
}`
|
||||
geoservice = `{"ip":"51.15.0.88","cc":"NL","city":"Haarlem","lat":52.381,"lon":4.6275,"gateways":["test1.riseup.net","test2.riseup.net"]}`
|
||||
cacert = `-----BEGIN CERTIFICATE-----
|
||||
MIIFjTCCA3WgAwIBAgIBATANBgkqhkiG9w0BAQ0FADBZMRgwFgYDVQQKDA9SaXNl
|
||||
dXAgTmV0d29ya3MxGzAZBgNVBAsMEmh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UE
|
||||
AwwXUmlzZXVwIE5ldHdvcmtzIFJvb3QgQ0EwHhcNMTQwNDI4MDAwMDAwWhcNMjQw
|
||||
NDI4MDAwMDAwWjBZMRgwFgYDVQQKDA9SaXNldXAgTmV0d29ya3MxGzAZBgNVBAsM
|
||||
Emh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UEAwwXUmlzZXVwIE5ldHdvcmtzIFJv
|
||||
b3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC76J4ciMJ8Sg0m
|
||||
TP7DF2DT9zNe0Csk4myoMFC57rfJeqsAlJCv1XMzBmXrw8wq/9z7XHv6n/0sWU7a
|
||||
7cF2hLR33ktjwODlx7vorU39/lXLndo492ZBhXQtG1INMShyv+nlmzO6GT7ESfNE
|
||||
LliFitEzwIegpMqxCIHXFuobGSCWF4N0qLHkq/SYUMoOJ96O3hmPSl1kFDRMtWXY
|
||||
iw1SEKjUvpyDJpVs3NGxeLCaA7bAWhDY5s5Yb2fA1o8ICAqhowurowJpW7n5ZuLK
|
||||
5VNTlNy6nZpkjt1QycYvNycffyPOFm/Q/RKDlvnorJIrihPkyniV3YY5cGgP+Qkx
|
||||
HUOT0uLA6LHtzfiyaOqkXwc4b0ZcQD5Vbf6Prd20Ppt6ei0zazkUPwxld3hgyw58
|
||||
m/4UIjG3PInWTNf293GngK2Bnz8Qx9e/6TueMSAn/3JBLem56E0WtmbLVjvko+LF
|
||||
PM5xA+m0BmuSJtrD1MUCXMhqYTtiOvgLBlUm5zkNxALzG+cXB28k6XikXt6MRG7q
|
||||
hzIPG38zwkooM55yy5i1YfcIi5NjMH6A+t4IJxxwb67MSb6UFOwg5kFokdONZcwj
|
||||
shczHdG9gLKSBIvrKa03Nd3W2dF9hMbRu//STcQxOailDBQCnXXfAATj9pYzdY4k
|
||||
ha8VCAREGAKTDAex9oXf1yRuktES4QIDAQABo2AwXjAdBgNVHQ4EFgQUC4tdmLVu
|
||||
f9hwfK4AGliaet5KkcgwDgYDVR0PAQH/BAQDAgIEMAwGA1UdEwQFMAMBAf8wHwYD
|
||||
VR0jBBgwFoAUC4tdmLVuf9hwfK4AGliaet5KkcgwDQYJKoZIhvcNAQENBQADggIB
|
||||
AGzL+GRnYu99zFoy0bXJKOGCF5XUXP/3gIXPRDqQf5g7Cu/jYMID9dB3No4Zmf7v
|
||||
qHjiSXiS8jx1j/6/Luk6PpFbT7QYm4QLs1f4BlfZOti2KE8r7KRDPIecUsUXW6P/
|
||||
3GJAVYH/+7OjA39za9AieM7+H5BELGccGrM5wfl7JeEz8in+V2ZWDzHQO4hMkiTQ
|
||||
4ZckuaL201F68YpiItBNnJ9N5nHr1MRiGyApHmLXY/wvlrOpclh95qn+lG6/2jk7
|
||||
3AmihLOKYMlPwPakJg4PYczm3icFLgTpjV5sq2md9bRyAg3oPGfAuWHmKj2Ikqch
|
||||
Td5CHKGxEEWbGUWEMP0s1A/JHWiCbDigc4Cfxhy56CWG4q0tYtnc2GMw8OAUO6Wf
|
||||
Xu5pYKNkzKSEtT/MrNJt44tTZWbKV/Pi/N2Fx36my7TgTUj7g3xcE9eF4JV2H/sg
|
||||
tsK3pwE0FEqGnT4qMFbixQmc8bGyuakr23wjMvfO7eZUxBuWYR2SkcP26sozF9PF
|
||||
tGhbZHQVGZUTVPyvwahMUEhbPGVerOW0IYpxkm0x/eaWdTc4vPpf/rIlgbAjarnJ
|
||||
UN9SaWRlWKSdP4haujnzCoJbM7dU9bjvlGZNyXEekgeT0W2qFeGGp+yyUWw8tNsp
|
||||
0BuC1b7uW/bBn/xKm319wXVDvBgZgcktMolak39V7DVO
|
||||
-----END CERTIFICATE-----`
|
||||
|
||||
eipserviceurl = "https://api.black.riseup.net:443/3/config/eip-service.json"
|
||||
providerurl = "https://riseup.net/provider.json"
|
||||
geoserviceurl = "https://api.black.riseup.net:9001/json"
|
||||
cacerturl = "https://black.riseup.net/ca.crt"
|
||||
openvpnurl1 = "tcpconnect://234.345.234.345:443"
|
||||
openvpnurl2 = "tcpconnect://123.456.123.456:443"
|
||||
obfs4url1 = "tcpconnect://234.345.234.345:23042"
|
||||
)
|
||||
|
||||
var RequestResponse = map[string]string{
|
||||
eipserviceurl: eipservice,
|
||||
providerurl: provider,
|
||||
geoserviceurl: geoservice,
|
||||
cacerturl: cacert,
|
||||
openvpnurl1: "",
|
||||
openvpnurl2: "",
|
||||
obfs4url1: "",
|
||||
}
|
||||
|
||||
func TestNewExperimentMeasurer(t *testing.T) {
|
||||
measurer := riseupvpn.NewExperimentMeasurer(riseupvpn.Config{})
|
||||
if measurer.ExperimentName() != "riseupvpn" {
|
||||
t.Fatal("unexpected name")
|
||||
}
|
||||
if measurer.ExperimentVersion() != "0.1.0" {
|
||||
if measurer.ExperimentVersion() != "0.2.0" {
|
||||
t.Fatal("unexpected version")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGood(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skip test in short mode")
|
||||
}
|
||||
measurer := riseupvpn.NewExperimentMeasurer(riseupvpn.Config{})
|
||||
measurement := new(model.Measurement)
|
||||
err := measurer.Run(
|
||||
context.Background(),
|
||||
&mockable.Session{
|
||||
MockableLogger: log.Log,
|
||||
},
|
||||
measurement,
|
||||
model.NewPrinterCallbacks(log.Log),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
measurement := runDefaultMockTest(t, generateDefaultMockGetter(map[string]bool{
|
||||
cacerturl: true,
|
||||
eipserviceurl: true,
|
||||
providerurl: true,
|
||||
geoserviceurl: true,
|
||||
openvpnurl1: true,
|
||||
openvpnurl2: true,
|
||||
obfs4url1: true,
|
||||
}))
|
||||
|
||||
tk := measurement.TestKeys.(*riseupvpn.TestKeys)
|
||||
if tk.Agent != "" {
|
||||
t.Fatal("unexpected Agent: " + tk.Agent)
|
||||
|
@ -59,21 +226,6 @@ func TestGood(t *testing.T) {
|
|||
if tk.Failure != nil {
|
||||
t.Fatal("unexpected Failure")
|
||||
}
|
||||
if len(tk.NetworkEvents) <= 0 {
|
||||
t.Fatal("no NetworkEvents?!")
|
||||
}
|
||||
if len(tk.Queries) <= 0 {
|
||||
t.Fatal("no Queries?!")
|
||||
}
|
||||
if len(tk.Requests) <= 0 {
|
||||
t.Fatal("no Requests?!")
|
||||
}
|
||||
if len(tk.TCPConnect) <= 0 {
|
||||
t.Fatal("no TCPConnect?!")
|
||||
}
|
||||
if len(tk.TLSHandshakes) <= 0 {
|
||||
t.Fatal("no TLSHandshakes?!")
|
||||
}
|
||||
if tk.APIFailure != nil {
|
||||
t.Fatal("unexpected ApiFailure")
|
||||
}
|
||||
|
@ -86,6 +238,12 @@ func TestGood(t *testing.T) {
|
|||
if tk.FailingGateways != nil {
|
||||
t.Fatal("unexpected FailingGateways value")
|
||||
}
|
||||
if tk.TransportStatus == nil {
|
||||
t.Fatal("unexpected nil TransportStatus struct ")
|
||||
}
|
||||
if tk.TransportStatus["openvpn"] != "ok" {
|
||||
t.Fatal("unexpected openvpn transport status")
|
||||
}
|
||||
}
|
||||
|
||||
// TestUpdateWithMixedResults tests if one operation failed
|
||||
|
@ -132,13 +290,39 @@ func TestUpdateWithMixedResults(t *testing.T) {
|
|||
if *tk.APIFailure != errorx.FailureEOFError {
|
||||
t.Fatal("invalid ApiFailure")
|
||||
}
|
||||
if tk.FailingGateways != nil {
|
||||
t.Fatal("invalid FailingGateways")
|
||||
}
|
||||
if tk.TransportStatus != nil {
|
||||
t.Fatal("invalid TransportStatus")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFailureCaCertFetch(t *testing.T) {
|
||||
measurer := riseupvpn.NewExperimentMeasurer(riseupvpn.Config{})
|
||||
func TestInvalidCaCert(t *testing.T) {
|
||||
requestResponseMap := map[string]string{
|
||||
eipserviceurl: eipservice,
|
||||
providerurl: provider,
|
||||
geoserviceurl: geoservice,
|
||||
cacerturl: "invalid",
|
||||
openvpnurl1: "",
|
||||
openvpnurl2: "",
|
||||
obfs4url1: "",
|
||||
}
|
||||
measurer := riseupvpn.Measurer{
|
||||
Config: riseupvpn.Config{},
|
||||
Getter: generateMockGetter(requestResponseMap, map[string]bool{
|
||||
cacerturl: true,
|
||||
eipserviceurl: true,
|
||||
providerurl: true,
|
||||
geoserviceurl: true,
|
||||
openvpnurl1: false,
|
||||
openvpnurl2: true,
|
||||
obfs4url1: true,
|
||||
}),
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
// we're cancelling immediately so that the CA Cert fetch fails
|
||||
cancel()
|
||||
defer cancel()
|
||||
|
||||
sess := &mockable.Session{MockableLogger: log.Log}
|
||||
measurement := new(model.Measurement)
|
||||
|
@ -147,6 +331,26 @@ func TestFailureCaCertFetch(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tk := measurement.TestKeys.(*riseupvpn.TestKeys)
|
||||
if tk.CACertStatus == true {
|
||||
t.Fatal("unexpected CaCertStatus")
|
||||
}
|
||||
if tk.APIStatus != "blocked" {
|
||||
t.Fatal("ApiStatus should be blocked")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFailureCaCertFetch(t *testing.T) {
|
||||
measurement := runDefaultMockTest(t, generateDefaultMockGetter(map[string]bool{
|
||||
cacerturl: false,
|
||||
eipserviceurl: true,
|
||||
providerurl: true,
|
||||
geoserviceurl: true,
|
||||
openvpnurl1: true,
|
||||
openvpnurl2: true,
|
||||
obfs4url1: true,
|
||||
}))
|
||||
|
||||
tk := measurement.TestKeys.(*riseupvpn.TestKeys)
|
||||
if tk.CACertStatus != false {
|
||||
t.Fatal("invalid CACertStatus ")
|
||||
|
@ -164,21 +368,15 @@ func TestFailureCaCertFetch(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFailureEipServiceBlocked(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skip test in short mode")
|
||||
}
|
||||
measurer := riseupvpn.NewExperimentMeasurer(riseupvpn.Config{})
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
selfcensor.Enable(`{"PoisonSystemDNS":{"api.black.riseup.net":["NXDOMAIN"]}}`)
|
||||
|
||||
sess := &mockable.Session{MockableLogger: log.Log}
|
||||
measurement := new(model.Measurement)
|
||||
callbacks := model.NewPrinterCallbacks(log.Log)
|
||||
err := measurer.Run(ctx, sess, measurement, callbacks)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
measurement := runDefaultMockTest(t, generateDefaultMockGetter(map[string]bool{
|
||||
cacerturl: true,
|
||||
eipserviceurl: false,
|
||||
providerurl: true,
|
||||
geoserviceurl: true,
|
||||
openvpnurl1: true,
|
||||
openvpnurl2: true,
|
||||
obfs4url1: true,
|
||||
}))
|
||||
tk := measurement.TestKeys.(*riseupvpn.TestKeys)
|
||||
if tk.CACertStatus != true {
|
||||
t.Fatal("invalid CACertStatus ")
|
||||
|
@ -202,21 +400,15 @@ func TestFailureEipServiceBlocked(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFailureProviderUrlBlocked(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skip test in short mode")
|
||||
}
|
||||
measurer := riseupvpn.NewExperimentMeasurer(riseupvpn.Config{})
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
selfcensor.Enable(`{"BlockedEndpoints":{"198.252.153.70:443":"REJECT"}}`)
|
||||
|
||||
sess := &mockable.Session{MockableLogger: log.Log}
|
||||
measurement := new(model.Measurement)
|
||||
callbacks := model.NewPrinterCallbacks(log.Log)
|
||||
err := measurer.Run(ctx, sess, measurement, callbacks)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
measurement := runDefaultMockTest(t, generateDefaultMockGetter(map[string]bool{
|
||||
cacerturl: true,
|
||||
eipserviceurl: true,
|
||||
providerurl: false,
|
||||
geoserviceurl: true,
|
||||
openvpnurl1: true,
|
||||
openvpnurl2: true,
|
||||
obfs4url1: true,
|
||||
}))
|
||||
tk := measurement.TestKeys.(*riseupvpn.TestKeys)
|
||||
|
||||
for _, entry := range tk.Requests {
|
||||
|
@ -240,21 +432,15 @@ func TestFailureProviderUrlBlocked(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestFailureGeoIpServiceBlocked(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skip test in short mode")
|
||||
}
|
||||
measurer := riseupvpn.NewExperimentMeasurer(riseupvpn.Config{})
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
selfcensor.Enable(`{"BlockedEndpoints":{"198.252.153.107:9001":"REJECT"}}`)
|
||||
|
||||
sess := &mockable.Session{MockableLogger: log.Log}
|
||||
measurement := new(model.Measurement)
|
||||
callbacks := model.NewPrinterCallbacks(log.Log)
|
||||
err := measurer.Run(ctx, sess, measurement, callbacks)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
measurement := runDefaultMockTest(t, generateDefaultMockGetter(map[string]bool{
|
||||
cacerturl: true,
|
||||
eipserviceurl: true,
|
||||
providerurl: true,
|
||||
geoserviceurl: false,
|
||||
openvpnurl1: true,
|
||||
openvpnurl2: true,
|
||||
obfs4url1: true,
|
||||
}))
|
||||
tk := measurement.TestKeys.(*riseupvpn.TestKeys)
|
||||
if tk.CACertStatus != true {
|
||||
t.Fatal("invalid CACertStatus ")
|
||||
|
@ -277,138 +463,16 @@ func TestFailureGeoIpServiceBlocked(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestFailureGateway(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skip test in short mode")
|
||||
}
|
||||
var testCases = [...]string{"openvpn", "obfs4"}
|
||||
eipService, err := fetchEipService()
|
||||
if err != nil {
|
||||
t.Log("Preconditions for the test are not met. Skipping due to: " + err.Error())
|
||||
t.SkipNow()
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("testing censored transport %s", tc), func(t *testing.T) {
|
||||
censoredGateway, err := selfCensorRandomGateway(eipService, tc)
|
||||
if err == nil {
|
||||
censorString := `{"BlockedEndpoints":{"` + censoredGateway.IP + `:` + censoredGateway.Port + `":"REJECT"}}`
|
||||
selfcensor.Enable(censorString)
|
||||
} else {
|
||||
t.Log("Preconditions for the test are not met. Skipping due to: " + err.Error())
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
// - run measurement
|
||||
runGatewayTest(t, censoredGateway)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type SelfCensoredGateway struct {
|
||||
IP string
|
||||
Port string
|
||||
}
|
||||
|
||||
func fetchEipService() (*riseupvpn.EipService, error) {
|
||||
// - fetch client cert and add to certpool
|
||||
caFetchClient := &http.Client{
|
||||
Timeout: time.Second * 30,
|
||||
}
|
||||
|
||||
caCertResponse, err := caFetchClient.Get("https://black.riseup.net/ca.crt")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var bodyString string
|
||||
|
||||
if caCertResponse.StatusCode != http.StatusOK {
|
||||
return nil, errors.New("unexpected HTTP response code")
|
||||
}
|
||||
bodyBytes, err := ioutil.ReadAll(caCertResponse.Body)
|
||||
defer caCertResponse.Body.Close()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodyString = string(bodyBytes)
|
||||
|
||||
certs := x509.NewCertPool()
|
||||
certs.AppendCertsFromPEM([]byte(bodyString))
|
||||
|
||||
// - fetch and parse eip-service.json
|
||||
client := &http.Client{
|
||||
Timeout: time.Second * 30,
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: certs,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
eipResponse, err := client.Get("https://api.black.riseup.net/3/config/eip-service.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if eipResponse.StatusCode != http.StatusOK {
|
||||
return nil, errors.New("Unexpected HTTP response code")
|
||||
}
|
||||
|
||||
bodyBytes, err = ioutil.ReadAll(eipResponse.Body)
|
||||
defer eipResponse.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodyString = string(bodyBytes)
|
||||
|
||||
eipService, err := riseupvpn.DecodeEIP3(bodyString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eipService, nil
|
||||
}
|
||||
|
||||
func selfCensorRandomGateway(eipService *riseupvpn.EipService, transportType string) (*SelfCensoredGateway, error) {
|
||||
|
||||
// - self censor random gateway
|
||||
gateways := eipService.Gateways
|
||||
if gateways == nil || len(gateways) == 0 {
|
||||
return nil, errors.New("No gateways found")
|
||||
}
|
||||
|
||||
var selfcensoredGateways []SelfCensoredGateway
|
||||
for _, gateway := range gateways {
|
||||
for _, transport := range gateway.Capabilities.Transport {
|
||||
if transport.Type == transportType {
|
||||
selfcensoredGateways = append(selfcensoredGateways, SelfCensoredGateway{IP: gateway.IPAddress, Port: transport.Ports[0]})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(selfcensoredGateways) == 0 {
|
||||
return nil, errors.New("transport " + transportType + " doesn't seem to be supported.")
|
||||
}
|
||||
|
||||
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
min := 0
|
||||
max := len(selfcensoredGateways) - 1
|
||||
randomIndex := rnd.Intn(max-min+1) + min
|
||||
return &selfcensoredGateways[randomIndex], nil
|
||||
|
||||
}
|
||||
|
||||
func runGatewayTest(t *testing.T, censoredGateway *SelfCensoredGateway) {
|
||||
measurer := riseupvpn.NewExperimentMeasurer(riseupvpn.Config{})
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
sess := &mockable.Session{MockableLogger: log.Log}
|
||||
measurement := new(model.Measurement)
|
||||
callbacks := model.NewPrinterCallbacks(log.Log)
|
||||
err := measurer.Run(ctx, sess, measurement, callbacks)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
func TestFailureGateway1(t *testing.T) {
|
||||
measurement := runDefaultMockTest(t, generateDefaultMockGetter(map[string]bool{
|
||||
cacerturl: true,
|
||||
eipserviceurl: true,
|
||||
providerurl: true,
|
||||
geoserviceurl: true,
|
||||
openvpnurl1: false,
|
||||
openvpnurl2: true,
|
||||
obfs4url1: true,
|
||||
}))
|
||||
tk := measurement.TestKeys.(*riseupvpn.TestKeys)
|
||||
if tk.CACertStatus != true {
|
||||
t.Fatal("invalid CACertStatus ")
|
||||
|
@ -418,18 +482,122 @@ func runGatewayTest(t *testing.T, censoredGateway *SelfCensoredGateway) {
|
|||
t.Fatal("unexpected amount of failing gateways")
|
||||
}
|
||||
|
||||
entry := tk.FailingGateways[0]
|
||||
if entry.IP != censoredGateway.IP || fmt.Sprint(entry.Port) != censoredGateway.Port {
|
||||
t.Fatal("unexpected failed gateway configuration")
|
||||
gw := tk.FailingGateways[0]
|
||||
if gw.IP != "234.345.234.345" {
|
||||
t.Fatal("invalid failed gateway ip: " + fmt.Sprint(gw.IP))
|
||||
}
|
||||
if gw.Port != 443 {
|
||||
t.Fatal("invalid failed gateway port: " + fmt.Sprint(gw.Port))
|
||||
}
|
||||
if gw.TransportType != "openvpn" {
|
||||
t.Fatal("invalid failed transport type: " + fmt.Sprint(gw.TransportType))
|
||||
}
|
||||
|
||||
if tk.APIStatus == "blocked" {
|
||||
t.Fatal("invalid ApiStatus", tk.APIStatus)
|
||||
t.Fatal("invalid ApiStatus")
|
||||
}
|
||||
|
||||
if tk.APIFailure != nil {
|
||||
t.Fatal("ApiFailure should be null")
|
||||
}
|
||||
|
||||
if tk.TransportStatus == nil || tk.TransportStatus["openvpn"] == "blocked" {
|
||||
t.Fatal("invalid TransportStatus: " + fmt.Sprint(tk.TransportStatus))
|
||||
}
|
||||
|
||||
if tk.TransportStatus == nil || tk.TransportStatus["obfs4"] == "blocked" {
|
||||
t.Fatal("invalid TransportStatus: " + fmt.Sprint(tk.TransportStatus))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFailureTransport(t *testing.T) {
|
||||
measurement := runDefaultMockTest(t, generateDefaultMockGetter(map[string]bool{
|
||||
cacerturl: true,
|
||||
eipserviceurl: true,
|
||||
providerurl: true,
|
||||
geoserviceurl: true,
|
||||
openvpnurl1: false,
|
||||
openvpnurl2: false,
|
||||
obfs4url1: false,
|
||||
}))
|
||||
tk := measurement.TestKeys.(*riseupvpn.TestKeys)
|
||||
|
||||
if tk.TransportStatus == nil || tk.TransportStatus["openvpn"] != "blocked" {
|
||||
t.Fatal("invalid TransportStatus: " + fmt.Sprint(tk.TransportStatus))
|
||||
}
|
||||
|
||||
if tk.TransportStatus == nil || tk.TransportStatus["obfs4"] != "blocked" {
|
||||
t.Fatal("invalid TransportStatus: " + fmt.Sprint(tk.TransportStatus))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMissingTransport(t *testing.T) {
|
||||
eipService, err := riseupvpn.DecodeEIP3(eipservice)
|
||||
if err != nil {
|
||||
t.Fatal("Preconditions for the test are not met.")
|
||||
}
|
||||
|
||||
//remove obfs4 capability from 2. gateway so that our
|
||||
//mock provider supports only openvpn
|
||||
index := -1
|
||||
transports := eipService.Gateways[1].Capabilities.Transport
|
||||
for i, transport := range transports {
|
||||
if transport.Type == "obfs4" {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if index == -1 {
|
||||
t.Fatal("Preconditions for the test are not met. Default eipservice string should contain obfs4 transport.")
|
||||
}
|
||||
|
||||
transports[index] = transports[len(transports)-1]
|
||||
transports = transports[:len(transports)-1]
|
||||
eipService.Gateways[1].Capabilities.Transport = transports
|
||||
eipservicejson, err := json.Marshal(eipservice)
|
||||
|
||||
requestResponseMap := map[string]string{
|
||||
eipserviceurl: string(eipservicejson),
|
||||
providerurl: provider,
|
||||
geoserviceurl: geoservice,
|
||||
cacerturl: cacert,
|
||||
openvpnurl1: "",
|
||||
openvpnurl2: "",
|
||||
obfs4url1: "",
|
||||
}
|
||||
|
||||
measurer := riseupvpn.Measurer{
|
||||
Config: riseupvpn.Config{},
|
||||
Getter: generateMockGetter(requestResponseMap, map[string]bool{
|
||||
cacerturl: true,
|
||||
eipserviceurl: true,
|
||||
providerurl: true,
|
||||
geoserviceurl: true,
|
||||
openvpnurl1: true,
|
||||
openvpnurl2: true,
|
||||
obfs4url1: false,
|
||||
}),
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
sess := &mockable.Session{MockableLogger: log.Log}
|
||||
measurement := new(model.Measurement)
|
||||
callbacks := model.NewPrinterCallbacks(log.Log)
|
||||
err = measurer.Run(ctx, sess, measurement, callbacks)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tk := measurement.TestKeys.(*riseupvpn.TestKeys)
|
||||
if tk.TransportStatus == nil || tk.TransportStatus["openvpn"] != "blocked" {
|
||||
t.Fatal("invalid TransportStatus: " + fmt.Sprint(tk.TransportStatus))
|
||||
}
|
||||
|
||||
if _, found := tk.TransportStatus["obfs"]; found {
|
||||
t.Fatal("invalid TransportStatus: " + fmt.Sprint(tk.TransportStatus))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestSummaryKeysInvalidType(t *testing.T) {
|
||||
|
@ -450,21 +618,27 @@ func TestSummaryKeysWorksAsIntended(t *testing.T) {
|
|||
APIStatus: "blocked",
|
||||
CACertStatus: true,
|
||||
FailingGateways: nil,
|
||||
TransportStatus: nil,
|
||||
},
|
||||
sk: riseupvpn.SummaryKeys{
|
||||
APIBlocked: true,
|
||||
ValidCACert: true,
|
||||
IsAnomaly: true,
|
||||
APIBlocked: true,
|
||||
ValidCACert: true,
|
||||
IsAnomaly: true,
|
||||
TransportStatus: nil,
|
||||
FailingGateways: 0,
|
||||
},
|
||||
}, {
|
||||
tk: riseupvpn.TestKeys{
|
||||
APIStatus: "ok",
|
||||
CACertStatus: false,
|
||||
FailingGateways: nil,
|
||||
TransportStatus: nil,
|
||||
},
|
||||
sk: riseupvpn.SummaryKeys{
|
||||
ValidCACert: false,
|
||||
IsAnomaly: true,
|
||||
ValidCACert: false,
|
||||
IsAnomaly: true,
|
||||
FailingGateways: 0,
|
||||
TransportStatus: nil,
|
||||
},
|
||||
}, {
|
||||
tk: riseupvpn.TestKeys{
|
||||
|
@ -475,13 +649,39 @@ func TestSummaryKeysWorksAsIntended(t *testing.T) {
|
|||
Port: 443,
|
||||
TransportType: "obfs4",
|
||||
}},
|
||||
TransportStatus: map[string]string{
|
||||
"obfs4": "blocked",
|
||||
"openvpn": "ok",
|
||||
},
|
||||
},
|
||||
sk: riseupvpn.SummaryKeys{
|
||||
FailingGateways: 1,
|
||||
IsAnomaly: true,
|
||||
ValidCACert: true,
|
||||
TransportStatus: map[string]string{
|
||||
"obfs4": "blocked",
|
||||
"openvpn": "ok",
|
||||
},
|
||||
},
|
||||
}}
|
||||
}, {
|
||||
tk: riseupvpn.TestKeys{
|
||||
APIStatus: "ok",
|
||||
CACertStatus: true,
|
||||
FailingGateways: nil,
|
||||
TransportStatus: map[string]string{
|
||||
"openvpn": "ok",
|
||||
},
|
||||
},
|
||||
sk: riseupvpn.SummaryKeys{
|
||||
ValidCACert: true,
|
||||
IsAnomaly: false,
|
||||
FailingGateways: 0,
|
||||
TransportStatus: map[string]string{
|
||||
"openvpn": "ok",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for idx, tt := range tests {
|
||||
t.Run(fmt.Sprintf("%d", idx), func(t *testing.T) {
|
||||
m := &riseupvpn.Measurer{}
|
||||
|
@ -498,3 +698,95 @@ func TestSummaryKeysWorksAsIntended(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func generateMockGetter(requestResponse map[string]string, responseStatus map[string]bool) urlgetter.MultiGetter {
|
||||
return func(ctx context.Context, g urlgetter.Getter) (urlgetter.TestKeys, error) {
|
||||
url := g.Target
|
||||
responseBody, foundRequest := requestResponse[url]
|
||||
isSuccessStatus, foundStatus := responseStatus[url]
|
||||
if !foundRequest || !foundStatus {
|
||||
return urlgetter.DefaultMultiGetter(ctx, g)
|
||||
}
|
||||
|
||||
var failure *string
|
||||
var failedOperation *string
|
||||
isBlocked := !isSuccessStatus
|
||||
var responseStatus int64 = 200
|
||||
|
||||
if isBlocked {
|
||||
responseBody = ""
|
||||
eofError := io.EOF.Error()
|
||||
failure = &eofError
|
||||
connectOperation := errorx.ConnectOperation
|
||||
failedOperation = &connectOperation
|
||||
responseStatus = 0
|
||||
}
|
||||
|
||||
tcpConnect := archival.TCPConnectEntry{
|
||||
// use some dummy IP/Port combination for URLs, we don't do DNS resolution
|
||||
IP: "123.456.234.123",
|
||||
Port: 443,
|
||||
Status: archival.TCPConnectStatus{
|
||||
Success: isSuccessStatus,
|
||||
Blocked: &isBlocked,
|
||||
Failure: failure,
|
||||
},
|
||||
}
|
||||
if strings.Contains(url, "tcpconnect://") {
|
||||
ipPort := strings.Split(strings.Split(url, "//")[1], ":")
|
||||
port, err := strconv.ParseInt(ipPort[1], 10, 32)
|
||||
if err == nil {
|
||||
tcpConnect.IP = ipPort[0]
|
||||
tcpConnect.Port = int(port)
|
||||
}
|
||||
}
|
||||
|
||||
tk := urlgetter.TestKeys{
|
||||
Failure: failure,
|
||||
FailedOperation: failedOperation,
|
||||
HTTPResponseStatus: responseStatus,
|
||||
HTTPResponseBody: responseBody,
|
||||
Requests: []archival.RequestEntry{archival.RequestEntry{
|
||||
Failure: failure,
|
||||
Request: archival.HTTPRequest{
|
||||
URL: url,
|
||||
Body: archival.MaybeBinaryValue{},
|
||||
BodyIsTruncated: false,
|
||||
},
|
||||
Response: archival.HTTPResponse{
|
||||
Body: archival.HTTPBody{
|
||||
Value: responseBody,
|
||||
},
|
||||
BodyIsTruncated: false,
|
||||
}},
|
||||
},
|
||||
TCPConnect: []archival.TCPConnectEntry{tcpConnect},
|
||||
}
|
||||
return tk, nil
|
||||
}
|
||||
}
|
||||
func generateDefaultMockGetter(responseStatuses map[string]bool) urlgetter.MultiGetter {
|
||||
return generateMockGetter(RequestResponse, responseStatuses)
|
||||
}
|
||||
|
||||
func runDefaultMockTest(t *testing.T, multiGetter urlgetter.MultiGetter) *model.Measurement {
|
||||
measurer := riseupvpn.Measurer{
|
||||
Config: riseupvpn.Config{},
|
||||
Getter: multiGetter,
|
||||
}
|
||||
|
||||
measurement := new(model.Measurement)
|
||||
err := measurer.Run(
|
||||
context.Background(),
|
||||
&mockable.Session{
|
||||
MockableLogger: log.Log,
|
||||
},
|
||||
measurement,
|
||||
model.NewPrinterCallbacks(log.Log),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return measurement
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user