2021-02-02 12:05:47 +01:00
package riseupvpn_test
import (
"context"
2021-03-30 12:02:51 +02:00
"encoding/json"
2021-04-02 17:58:36 +02:00
"errors"
2021-02-02 12:05:47 +01:00
"fmt"
2021-03-30 12:02:51 +02:00
"io"
"strconv"
"strings"
2021-02-02 12:05:47 +01:00
"testing"
2021-03-30 12:02:51 +02:00
2021-02-02 12:05:47 +01:00
"github.com/apex/log"
"github.com/google/go-cmp/cmp"
"github.com/ooni/probe-cli/v3/internal/engine/experiment/riseupvpn"
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
2021-06-22 00:12:03 +02:00
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
2022-01-03 13:53:23 +01:00
"github.com/ooni/probe-cli/v3/internal/model"
2021-09-28 12:42:01 +02:00
"github.com/ooni/probe-cli/v3/internal/netxlite"
2022-06-02 00:50:55 +02:00
"github.com/ooni/probe-cli/v3/internal/tracex"
2021-02-02 12:05:47 +01:00
)
2021-03-30 12:02:51 +02:00
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 / 9 z7XHv6n / 0 sWU7a
7 cF2hLR33ktjwODlx7vorU39 / lXLndo492ZBhXQtG1INMShyv + nlmzO6GT7ESfNE
LliFitEzwIegpMqxCIHXFuobGSCWF4N0qLHkq / SYUMoOJ96O3hmPSl1kFDRMtWXY
iw1SEKjUvpyDJpVs3NGxeLCaA7bAWhDY5s5Yb2fA1o8ICAqhowurowJpW7n5ZuLK
5 VNTlNy6nZpkjt1QycYvNycffyPOFm / Q / RKDlvnorJIrihPkyniV3YY5cGgP + Qkx
HUOT0uLA6LHtzfiyaOqkXwc4b0ZcQD5Vbf6Prd20Ppt6ei0zazkUPwxld3hgyw58
m / 4 UIjG3PInWTNf293GngK2Bnz8Qx9e / 6 TueMSAn / 3 JBLem56E0WtmbLVjvko + LF
PM5xA + m0BmuSJtrD1MUCXMhqYTtiOvgLBlUm5zkNxALzG + cXB28k6XikXt6MRG7q
hzIPG38zwkooM55yy5i1YfcIi5NjMH6A + t4IJxxwb67MSb6UFOwg5kFokdONZcwj
shczHdG9gLKSBIvrKa03Nd3W2dF9hMbRu //STcQxOailDBQCnXXfAATj9pYzdY4k
ha8VCAREGAKTDAex9oXf1yRuktES4QIDAQABo2AwXjAdBgNVHQ4EFgQUC4tdmLVu
f9hwfK4AGliaet5KkcgwDgYDVR0PAQH / BAQDAgIEMAwGA1UdEwQFMAMBAf8wHwYD
VR0jBBgwFoAUC4tdmLVuf9hwfK4AGliaet5KkcgwDQYJKoZIhvcNAQENBQADggIB
AGzL + GRnYu99zFoy0bXJKOGCF5XUXP / 3 gIXPRDqQf5g7Cu / jYMID9dB3No4Zmf7v
qHjiSXiS8jx1j / 6 / Luk6PpFbT7QYm4QLs1f4BlfZOti2KE8r7KRDPIecUsUXW6P /
3 GJAVYH / + 7 OjA39za9AieM7 + H5BELGccGrM5wfl7JeEz8in + V2ZWDzHQO4hMkiTQ
4 ZckuaL201F68YpiItBNnJ9N5nHr1MRiGyApHmLXY / wvlrOpclh95qn + lG6 / 2 jk7
3 AmihLOKYMlPwPakJg4PYczm3icFLgTpjV5sq2md9bRyAg3oPGfAuWHmKj2Ikqch
Td5CHKGxEEWbGUWEMP0s1A / JHWiCbDigc4Cfxhy56CWG4q0tYtnc2GMw8OAUO6Wf
Xu5pYKNkzKSEtT / MrNJt44tTZWbKV / Pi / N2Fx36my7TgTUj7g3xcE9eF4JV2H / sg
tsK3pwE0FEqGnT4qMFbixQmc8bGyuakr23wjMvfO7eZUxBuWYR2SkcP26sozF9PF
tGhbZHQVGZUTVPyvwahMUEhbPGVerOW0IYpxkm0x / eaWdTc4vPpf / rIlgbAjarnJ
UN9SaWRlWKSdP4haujnzCoJbM7dU9bjvlGZNyXEekgeT0W2qFeGGp + yyUWw8tNsp
0 BuC1b7uW / bBn / xKm319wXVDvBgZgcktMolak39V7DVO
-- -- - END CERTIFICATE -- -- - `
2021-04-02 17:58:36 +02:00
// TODO(bassosimone): maybe we can switch this test to internal
// testing (since now it's all unit tested!) and just use the
// same constants that are used in riseupvpn.go.
2021-03-30 12:02:51 +02:00
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 : "" ,
}
2021-02-02 12:05:47 +01:00
func TestNewExperimentMeasurer ( t * testing . T ) {
measurer := riseupvpn . NewExperimentMeasurer ( riseupvpn . Config { } )
if measurer . ExperimentName ( ) != "riseupvpn" {
t . Fatal ( "unexpected name" )
}
2021-03-30 12:02:51 +02:00
if measurer . ExperimentVersion ( ) != "0.2.0" {
2021-02-02 12:05:47 +01:00
t . Fatal ( "unexpected version" )
}
}
func TestGood ( t * testing . T ) {
2021-03-30 12:02:51 +02:00
measurement := runDefaultMockTest ( t , generateDefaultMockGetter ( map [ string ] bool {
cacerturl : true ,
eipserviceurl : true ,
providerurl : true ,
geoserviceurl : true ,
openvpnurl1 : true ,
openvpnurl2 : true ,
obfs4url1 : true ,
} ) )
2021-02-02 12:05:47 +01:00
tk := measurement . TestKeys . ( * riseupvpn . TestKeys )
if tk . Agent != "" {
t . Fatal ( "unexpected Agent: " + tk . Agent )
}
if tk . FailedOperation != nil {
t . Fatal ( "unexpected FailedOperation" )
}
if tk . Failure != nil {
t . Fatal ( "unexpected Failure" )
}
if tk . APIFailure != nil {
t . Fatal ( "unexpected ApiFailure" )
}
if tk . APIStatus != "ok" {
t . Fatal ( "unexpected ApiStatus" )
}
if tk . CACertStatus != true {
t . Fatal ( "unexpected CaCertStatus" )
}
if tk . FailingGateways != nil {
t . Fatal ( "unexpected FailingGateways value" )
}
2021-03-30 12:02:51 +02:00
if tk . TransportStatus == nil {
t . Fatal ( "unexpected nil TransportStatus struct " )
}
if tk . TransportStatus [ "openvpn" ] != "ok" {
t . Fatal ( "unexpected openvpn transport status" )
}
2021-02-02 12:05:47 +01:00
}
// TestUpdateWithMixedResults tests if one operation failed
// ApiStatus is considered as blocked
func TestUpdateWithMixedResults ( t * testing . T ) {
tk := riseupvpn . NewTestKeys ( )
tk . UpdateProviderAPITestKeys ( urlgetter . MultiOutput {
Input : urlgetter . MultiInput {
Config : urlgetter . Config { Method : "GET" } ,
Target : "https://api.black.riseup.net:443/3/config/eip-service.json" ,
} ,
TestKeys : urlgetter . TestKeys {
HTTPResponseStatus : 200 ,
} ,
} )
tk . UpdateProviderAPITestKeys ( urlgetter . MultiOutput {
Input : urlgetter . MultiInput {
Config : urlgetter . Config { Method : "GET" } ,
Target : "https://riseup.net/provider.json" ,
} ,
TestKeys : urlgetter . TestKeys {
FailedOperation : ( func ( ) * string {
2021-09-28 12:42:01 +02:00
s := netxlite . HTTPRoundTripOperation
2021-02-02 12:05:47 +01:00
return & s
} ) ( ) ,
Failure : ( func ( ) * string {
2021-09-28 12:42:01 +02:00
s := netxlite . FailureEOFError
2021-02-02 12:05:47 +01:00
return & s
} ) ( ) ,
} ,
} )
tk . UpdateProviderAPITestKeys ( urlgetter . MultiOutput {
Input : urlgetter . MultiInput {
Config : urlgetter . Config { Method : "GET" } ,
Target : "https://api.black.riseup.net:9001/json" ,
} ,
TestKeys : urlgetter . TestKeys {
HTTPResponseStatus : 200 ,
} ,
} )
if tk . APIStatus != "blocked" {
t . Fatal ( "ApiStatus should be blocked" )
}
2021-09-28 12:42:01 +02:00
if * tk . APIFailure != netxlite . FailureEOFError {
2021-02-02 12:05:47 +01:00
t . Fatal ( "invalid ApiFailure" )
}
2021-03-30 12:02:51 +02:00
if tk . FailingGateways != nil {
t . Fatal ( "invalid FailingGateways" )
}
if tk . TransportStatus != nil {
t . Fatal ( "invalid TransportStatus" )
}
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
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 ,
} ) ,
}
2021-04-02 17:58:36 +02:00
ctx := context . Background ( )
2021-02-02 12:05:47 +01:00
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 )
}
2021-03-30 12:02:51 +02:00
tk := measurement . TestKeys . ( * riseupvpn . TestKeys )
if tk . CACertStatus == true {
t . Fatal ( "unexpected CaCertStatus" )
}
if tk . APIStatus != "blocked" {
t . Fatal ( "ApiStatus should be blocked" )
}
2021-04-02 17:58:36 +02:00
if tk . FailingGateways != nil {
t . Fatal ( "invalid FailingGateways" )
}
if tk . TransportStatus != nil {
t . Fatal ( "invalid TransportStatus" )
}
2021-03-30 12:02:51 +02:00
}
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 ,
} ) )
2021-02-02 12:05:47 +01:00
tk := measurement . TestKeys . ( * riseupvpn . TestKeys )
if tk . CACertStatus != false {
t . Fatal ( "invalid CACertStatus " )
}
if tk . APIStatus != "blocked" {
t . Fatal ( "invalid ApiStatus" )
}
if tk . APIFailure != nil {
t . Fatal ( "ApiFailure should be null" )
}
if len ( tk . Requests ) > 1 {
t . Fatal ( "Unexpected requests" )
}
2021-04-02 17:58:36 +02:00
if tk . FailingGateways != nil {
t . Fatal ( "invalid FailingGateways" )
}
if tk . TransportStatus != nil {
t . Fatal ( "invalid TransportStatus" )
}
2021-02-02 12:05:47 +01:00
}
func TestFailureEipServiceBlocked ( t * testing . T ) {
2021-03-30 12:02:51 +02:00
measurement := runDefaultMockTest ( t , generateDefaultMockGetter ( map [ string ] bool {
cacerturl : true ,
eipserviceurl : false ,
providerurl : true ,
geoserviceurl : true ,
openvpnurl1 : true ,
openvpnurl2 : true ,
obfs4url1 : true ,
} ) )
2021-02-02 12:05:47 +01:00
tk := measurement . TestKeys . ( * riseupvpn . TestKeys )
if tk . CACertStatus != true {
2021-04-02 17:58:36 +02:00
t . Fatal ( "invalid CACertStatus" )
2021-02-02 12:05:47 +01:00
}
for _ , entry := range tk . Requests {
if entry . Request . URL == "https://api.black.riseup.net:443/3/config/eip-service.json" {
if entry . Failure == nil {
t . Fatal ( "Failure for " + entry . Request . URL + " should not be null" )
}
}
}
if tk . APIStatus != "blocked" {
t . Fatal ( "invalid ApiStatus" )
}
if tk . APIFailure == nil {
t . Fatal ( "ApiFailure should not be null" )
}
}
func TestFailureProviderUrlBlocked ( t * testing . T ) {
2021-03-30 12:02:51 +02:00
measurement := runDefaultMockTest ( t , generateDefaultMockGetter ( map [ string ] bool {
cacerturl : true ,
eipserviceurl : true ,
providerurl : false ,
geoserviceurl : true ,
openvpnurl1 : true ,
openvpnurl2 : true ,
obfs4url1 : true ,
} ) )
2021-02-02 12:05:47 +01:00
tk := measurement . TestKeys . ( * riseupvpn . TestKeys )
for _ , entry := range tk . Requests {
if entry . Request . URL == "https://riseup.net/provider.json" {
if entry . Failure == nil {
t . Fatal ( "Failure for " + entry . Request . URL + " should not be null" )
}
}
}
if tk . CACertStatus != true {
t . Fatal ( "invalid CACertStatus " )
}
if tk . APIStatus != "blocked" {
t . Fatal ( "invalid ApiStatus" )
}
if tk . APIFailure == nil {
t . Fatal ( "ApiFailure should not be null" )
}
}
func TestFailureGeoIpServiceBlocked ( t * testing . T ) {
2021-03-30 12:02:51 +02:00
measurement := runDefaultMockTest ( t , generateDefaultMockGetter ( map [ string ] bool {
cacerturl : true ,
eipserviceurl : true ,
providerurl : true ,
geoserviceurl : false ,
openvpnurl1 : true ,
openvpnurl2 : true ,
obfs4url1 : true ,
} ) )
2021-02-02 12:05:47 +01:00
tk := measurement . TestKeys . ( * riseupvpn . TestKeys )
if tk . CACertStatus != true {
t . Fatal ( "invalid CACertStatus " )
}
for _ , entry := range tk . Requests {
if entry . Request . URL == "https://api.black.riseup.net:9001/json" {
if entry . Failure == nil {
t . Fatal ( "Failure for " + entry . Request . URL + " should not be null" )
}
}
}
if tk . APIStatus != "blocked" {
t . Fatal ( "invalid ApiStatus" )
}
if tk . APIFailure == nil {
t . Fatal ( "ApiFailure should not be null" )
}
}
2021-03-30 12:02:51 +02:00
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 " )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
if tk . FailingGateways == nil || len ( tk . FailingGateways ) != 1 {
t . Fatal ( "unexpected amount of failing gateways" )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
gw := tk . FailingGateways [ 0 ]
if gw . IP != "234.345.234.345" {
t . Fatal ( "invalid failed gateway ip: " + fmt . Sprint ( gw . IP ) )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
if gw . Port != 443 {
t . Fatal ( "invalid failed gateway port: " + fmt . Sprint ( gw . Port ) )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
if gw . TransportType != "openvpn" {
t . Fatal ( "invalid failed transport type: " + fmt . Sprint ( gw . TransportType ) )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
if tk . APIStatus == "blocked" {
t . Fatal ( "invalid ApiStatus" )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
if tk . APIFailure != nil {
t . Fatal ( "ApiFailure should be null" )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
if tk . TransportStatus == nil || tk . TransportStatus [ "openvpn" ] == "blocked" {
t . Fatal ( "invalid TransportStatus: " + fmt . Sprint ( tk . TransportStatus ) )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
if tk . TransportStatus == nil || tk . TransportStatus [ "obfs4" ] == "blocked" {
t . Fatal ( "invalid TransportStatus: " + fmt . Sprint ( tk . TransportStatus ) )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
}
2021-02-02 12:05:47 +01:00
2021-03-30 12:02:51 +02:00
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 ) )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
if tk . TransportStatus == nil || tk . TransportStatus [ "obfs4" ] != "blocked" {
t . Fatal ( "invalid TransportStatus: " + fmt . Sprint ( tk . TransportStatus ) )
2021-02-02 12:05:47 +01:00
}
}
2021-03-30 12:02:51 +02:00
func TestMissingTransport ( t * testing . T ) {
eipService , err := riseupvpn . DecodeEIP3 ( eipservice )
if err != nil {
t . Fatal ( "Preconditions for the test are not met." )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
//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
2021-02-02 12:05:47 +01:00
}
}
2021-03-30 12:02:51 +02:00
if index == - 1 {
t . Fatal ( "Preconditions for the test are not met. Default eipservice string should contain obfs4 transport." )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
transports [ index ] = transports [ len ( transports ) - 1 ]
transports = transports [ : len ( transports ) - 1 ]
eipService . Gateways [ 1 ] . Capabilities . Transport = transports
eipservicejson , err := json . Marshal ( eipservice )
2021-03-31 15:59:19 +02:00
if err != nil {
t . Fatal ( err )
}
2021-02-02 12:05:47 +01:00
2021-03-30 12:02:51 +02:00
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 ,
} ) ,
}
2021-02-02 12:05:47 +01:00
2021-04-02 17:58:36 +02:00
ctx := context . Background ( )
2021-02-02 12:05:47 +01:00
sess := & mockable . Session { MockableLogger : log . Log }
measurement := new ( model . Measurement )
callbacks := model . NewPrinterCallbacks ( log . Log )
2021-03-30 12:02:51 +02:00
err = measurer . Run ( ctx , sess , measurement , callbacks )
2021-02-02 12:05:47 +01:00
if err != nil {
t . Fatal ( err )
}
tk := measurement . TestKeys . ( * riseupvpn . TestKeys )
2021-03-30 12:02:51 +02:00
if tk . TransportStatus == nil || tk . TransportStatus [ "openvpn" ] != "blocked" {
t . Fatal ( "invalid TransportStatus: " + fmt . Sprint ( tk . TransportStatus ) )
2021-02-02 12:05:47 +01:00
}
2021-03-30 12:02:51 +02:00
if _ , found := tk . TransportStatus [ "obfs" ] ; found {
t . Fatal ( "invalid TransportStatus: " + fmt . Sprint ( tk . TransportStatus ) )
2021-02-02 12:05:47 +01:00
}
}
func TestSummaryKeysInvalidType ( t * testing . T ) {
measurement := new ( model . Measurement )
m := & riseupvpn . Measurer { }
_ , err := m . GetSummaryKeys ( measurement )
if err . Error ( ) != "invalid test keys type" {
t . Fatal ( "not the error we expected" )
}
}
func TestSummaryKeysWorksAsIntended ( t * testing . T ) {
tests := [ ] struct {
tk riseupvpn . TestKeys
sk riseupvpn . SummaryKeys
} { {
tk : riseupvpn . TestKeys {
APIStatus : "blocked" ,
CACertStatus : true ,
FailingGateways : nil ,
2021-03-30 12:02:51 +02:00
TransportStatus : nil ,
2021-02-02 12:05:47 +01:00
} ,
sk : riseupvpn . SummaryKeys {
2021-03-30 12:02:51 +02:00
APIBlocked : true ,
ValidCACert : true ,
IsAnomaly : true ,
TransportStatus : nil ,
FailingGateways : 0 ,
2021-02-02 12:05:47 +01:00
} ,
} , {
tk : riseupvpn . TestKeys {
APIStatus : "ok" ,
CACertStatus : false ,
FailingGateways : nil ,
2021-03-30 12:02:51 +02:00
TransportStatus : nil ,
2021-02-02 12:05:47 +01:00
} ,
sk : riseupvpn . SummaryKeys {
2021-03-30 12:02:51 +02:00
ValidCACert : false ,
IsAnomaly : true ,
FailingGateways : 0 ,
TransportStatus : nil ,
2021-02-02 12:05:47 +01:00
} ,
} , {
tk : riseupvpn . TestKeys {
APIStatus : "ok" ,
CACertStatus : true ,
FailingGateways : [ ] riseupvpn . GatewayConnection { {
IP : "1.1.1.1" ,
Port : 443 ,
TransportType : "obfs4" ,
} } ,
2021-03-30 12:02:51 +02:00
TransportStatus : map [ string ] string {
"obfs4" : "blocked" ,
"openvpn" : "ok" ,
} ,
2021-02-02 12:05:47 +01:00
} ,
sk : riseupvpn . SummaryKeys {
FailingGateways : 1 ,
IsAnomaly : true ,
ValidCACert : true ,
2021-03-30 12:02:51 +02:00
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" ,
} ,
2021-02-02 12:05:47 +01:00
} ,
2021-03-30 12:02:51 +02:00
} ,
}
2021-02-02 12:05:47 +01:00
for idx , tt := range tests {
t . Run ( fmt . Sprintf ( "%d" , idx ) , func ( t * testing . T ) {
m := & riseupvpn . Measurer { }
measurement := & model . Measurement { TestKeys : & tt . tk }
got , err := m . GetSummaryKeys ( measurement )
if err != nil {
t . Fatal ( err )
return
}
sk := got . ( riseupvpn . SummaryKeys )
if diff := cmp . Diff ( tt . sk , sk ) ; diff != "" {
t . Fatal ( diff )
}
} )
}
}
2021-03-30 12:02:51 +02:00
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 {
2021-04-02 17:58:36 +02:00
return urlgetter . TestKeys { } , errors . New ( "request or status not found" )
2021-03-30 12:02:51 +02:00
}
var failure * string
var failedOperation * string
isBlocked := ! isSuccessStatus
var responseStatus int64 = 200
if isBlocked {
responseBody = ""
eofError := io . EOF . Error ( )
failure = & eofError
2021-09-28 12:42:01 +02:00
connectOperation := netxlite . ConnectOperation
2021-03-30 12:02:51 +02:00
failedOperation = & connectOperation
responseStatus = 0
}
2022-05-31 21:53:01 +02:00
tcpConnect := tracex . TCPConnectEntry {
2021-03-30 12:02:51 +02:00
// use some dummy IP/Port combination for URLs, we don't do DNS resolution
IP : "123.456.234.123" ,
Port : 443 ,
2022-05-31 21:53:01 +02:00
Status : tracex . TCPConnectStatus {
2021-03-30 12:02:51 +02:00
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 ,
2022-05-31 21:53:01 +02:00
Requests : [ ] tracex . RequestEntry { {
2021-03-30 12:02:51 +02:00
Failure : failure ,
2022-05-31 21:53:01 +02:00
Request : tracex . HTTPRequest {
2021-03-30 12:02:51 +02:00
URL : url ,
2022-05-31 21:53:01 +02:00
Body : tracex . MaybeBinaryValue { } ,
2021-03-30 12:02:51 +02:00
BodyIsTruncated : false ,
} ,
2022-05-31 21:53:01 +02:00
Response : tracex . HTTPResponse {
Body : tracex . HTTPBody {
2021-03-30 12:02:51 +02:00
Value : responseBody ,
} ,
BodyIsTruncated : false ,
} } ,
} ,
2022-05-31 21:53:01 +02:00
TCPConnect : [ ] tracex . TCPConnectEntry { tcpConnect } ,
2021-03-30 12:02:51 +02:00
}
return tk , nil
}
}
2021-04-02 17:58:36 +02:00
2021-03-30 12:02:51 +02:00
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
}