Sfoglia il codice sorgente

add more clientlib tests (#2)

Co-authored-by: rosalinddeibert <rosalind.deibert@mail.utoronto.ca>
Adam Pritchard 1 anno fa
parent
commit
6918f7a04f
1 ha cambiato i file con 104 aggiunte e 113 eliminazioni
  1. 104 113
      ClientLibrary/clientlib/clientlib_test.go

+ 104 - 113
ClientLibrary/clientlib/clientlib_test.go

@@ -22,7 +22,9 @@ package clientlib
 import (
 	"context"
 	"encoding/json"
+	"errors"
 	"os"
+	"strings"
 	"testing"
 	"time"
 
@@ -30,50 +32,61 @@ import (
 	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/protocol"
 )
 
-func TestStartTunnel(t *testing.T) {
-	// TODO: More comprehensive tests. This is only a smoke test.
-
-	clientPlatform := "clientlib_test.go"
-	networkID := "UNKNOWN"
-	timeout := 60
-	quickTimeout := 1
-	trueVal := true
-
+func setupConfig(t *testing.T, disableFetcher bool) []byte {
 	configJSON, err := os.ReadFile("../../psiphon/controller_test.config")
 	if err != nil {
-		// Skip, don't fail, if config file is not present
+		// What to do if config file is not present?
 		t.Skipf("error loading configuration file: %s", err)
 	}
 
-	// Initialize a fresh datastore and create a modified config which cannot
-	// connect without known servers, to be used in timeout cases.
-
-	testDataDirName, err := os.MkdirTemp("", "psiphon-clientlib-test")
-	if err != nil {
-		t.Fatalf("ioutil.TempDir failed: %v", err)
-	}
-	defer os.RemoveAll(testDataDirName)
-
 	var config map[string]interface{}
 	err = json.Unmarshal(configJSON, &config)
 	if err != nil {
 		t.Fatalf("json.Unmarshal failed: %v", err)
 	}
 
-	// Use the legacy encoding to both exercise that case, and facilitate a
-	// gradual network upgrade to new encoding support.
+	// Use the legacy encoding to both exercise that case, and facilitate a gradual
+	// network upgrade to new encoding support.
 	config["TargetAPIEncoding"] = protocol.PSIPHON_API_ENCODING_JSON
 
+	if disableFetcher {
+		config["DisableRemoteServerListFetcher"] = true
+	}
+
 	configJSON, err = json.Marshal(config)
 	if err != nil {
 		t.Fatalf("json.Marshal failed: %v", err)
 	}
 
-	config["DisableRemoteServerListFetcher"] = true
+	return configJSON
+}
+
+func TestStartTunnel(t *testing.T) {
+	// TODO: More comprehensive tests. This is only a smoke test.
+
+	configJSON := setupConfig(t, false)
+	configJSONNoFetcher := setupConfig(t, true)
 
-	configJSONNoFetcher, err := json.Marshal(config)
+	clientPlatform := "clientlib_test.go"
+	networkID := "UNKNOWN"
+	timeout := 60
+	quickTimeout := 1
+	trueVal := true
+
+	// Initialize a fresh datastore and create a modified config which cannot
+	// connect without known servers, to be used in timeout cases.
+
+	testDataDirName, err := os.MkdirTemp("", "psiphon-clientlib-test")
 	if err != nil {
-		t.Fatalf("json.Marshal failed: %v", err)
+		t.Fatalf("ioutil.TempDir failed: %v", err)
+	}
+	defer os.RemoveAll(testDataDirName)
+
+	paramsDeltaErr := func(err error) bool {
+		return strings.Contains(err.Error(), "SetParameters failed for delta")
+	}
+	timeoutErr := func(err error) bool {
+		return errors.Is(err, ErrTimeout)
 	}
 
 	type args struct {
@@ -88,7 +101,7 @@ func TestStartTunnel(t *testing.T) {
 		name        string
 		args        args
 		wantTunnel  bool
-		expectedErr error
+		expectedErr func(error) bool
 	}{
 		{
 			name: "Failure: context timeout",
@@ -106,7 +119,7 @@ func TestStartTunnel(t *testing.T) {
 				noticeReceiver: nil,
 			},
 			wantTunnel:  false,
-			expectedErr: ErrTimeout,
+			expectedErr: timeoutErr,
 		},
 		{
 			name: "Failure: config timeout",
@@ -124,7 +137,7 @@ func TestStartTunnel(t *testing.T) {
 				noticeReceiver: nil,
 			},
 			wantTunnel:  false,
-			expectedErr: ErrTimeout,
+			expectedErr: timeoutErr,
 		},
 		{
 			name: "Success: simple",
@@ -202,6 +215,42 @@ func TestStartTunnel(t *testing.T) {
 			wantTunnel:  true,
 			expectedErr: nil,
 		},
+		{
+			name: "Success: good ParametersDelta",
+			args: args{
+				ctxTimeout:              0,
+				configJSON:              configJSON,
+				embeddedServerEntryList: "",
+				params: Parameters{
+					DataRootDirectory:             &testDataDirName,
+					ClientPlatform:                &clientPlatform,
+					NetworkID:                     &networkID,
+					EstablishTunnelTimeoutSeconds: &timeout,
+				},
+				paramsDelta:    ParametersDelta{"NetworkLatencyMultiplierMin": 1},
+				noticeReceiver: nil,
+			},
+			wantTunnel:  true,
+			expectedErr: nil,
+		},
+		{
+			name: "Failure: bad ParametersDelta",
+			args: args{
+				ctxTimeout:              0,
+				configJSON:              configJSON,
+				embeddedServerEntryList: "",
+				params: Parameters{
+					DataRootDirectory:             &testDataDirName,
+					ClientPlatform:                &clientPlatform,
+					NetworkID:                     &networkID,
+					EstablishTunnelTimeoutSeconds: &timeout,
+				},
+				paramsDelta:    ParametersDelta{"invalidParam": 1},
+				noticeReceiver: nil,
+			},
+			wantTunnel:  false,
+			expectedErr: paramsDeltaErr,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -234,8 +283,16 @@ func TestStartTunnel(t *testing.T) {
 				t.Errorf("StartTunnel() gotTunnel = %v, wantTunnel %v", err, tt.wantTunnel)
 			}
 
-			if err != tt.expectedErr {
-				t.Fatalf("StartTunnel() error = %v, expectedErr %v", err, tt.expectedErr)
+			if tt.expectedErr == nil {
+				if err != nil {
+					t.Fatalf("StartTunnel() returned unexpected error: %v", err)
+				}
+			} else if !tt.expectedErr(err) {
+				t.Fatalf("StartTunnel() error: %v", err)
+				return
+			}
+
+			if err != nil {
 				return
 			}
 
@@ -267,27 +324,7 @@ func TestStartTunnel(t *testing.T) {
 }
 
 func TestMultipleStartTunnel(t *testing.T) {
-	configJSON, err := os.ReadFile("../../psiphon/controller_test.config")
-	if err != nil {
-		// What to do if config file is not present?
-		t.Skipf("error loading configuration file: %s", err)
-	}
-
-	var config map[string]interface{}
-	err = json.Unmarshal(configJSON, &config)
-	if err != nil {
-		t.Fatalf("json.Unmarshal failed: %v", err)
-	}
-
-	// Use the legacy encoding to both exercise that case, and facilitate a
-	// gradual network upgrade to new encoding support.
-	config["TargetAPIEncoding"] = protocol.PSIPHON_API_ENCODING_JSON
-
-	configJSON, err = json.Marshal(config)
-	if err != nil {
-		t.Fatalf("json.Marshal failed: %v", err)
-	}
-
+	configJSON := setupConfig(t, false)
 	testDataDirName, err := os.MkdirTemp("", "psiphon-clientlib-test")
 	if err != nil {
 		t.Fatalf("ioutil.TempDir failed: %v", err)
@@ -340,27 +377,8 @@ func TestMultipleStartTunnel(t *testing.T) {
 }
 
 func TestPsiphonTunnel_Dial(t *testing.T) {
+	configJSON := setupConfig(t, false)
 	trueVal := true
-	configJSON, err := os.ReadFile("../../psiphon/controller_test.config")
-	if err != nil {
-		// Skip, don't fail, if config file is not present
-		t.Skipf("error loading configuration file: %s", err)
-	}
-
-	var config map[string]interface{}
-	err = json.Unmarshal(configJSON, &config)
-	if err != nil {
-		t.Fatalf("json.Unmarshal failed: %v", err)
-	}
-
-	// Use the legacy encoding to both exercise that case, and facilitate a
-	// gradual network upgrade to new encoding support.
-	config["TargetAPIEncoding"] = protocol.PSIPHON_API_ENCODING_JSON
-
-	configJSON, err = json.Marshal(config)
-	if err != nil {
-		t.Fatalf("json.Marshal failed: %v", err)
-	}
 
 	testDataDirName, err := os.MkdirTemp("", "psiphon-clientlib-test")
 	if err != nil {
@@ -372,9 +390,10 @@ func TestPsiphonTunnel_Dial(t *testing.T) {
 		remoteAddr string
 	}
 	tests := []struct {
-		name    string
-		args    args
-		wantErr bool
+		name          string
+		args          args
+		wantErr       bool
+		tunnelStopped bool
 	}{
 		{
 			name:    "Success: example.com",
@@ -386,6 +405,12 @@ func TestPsiphonTunnel_Dial(t *testing.T) {
 			args:    args{remoteAddr: "example.com:99999"},
 			wantErr: true,
 		},
+		{
+			name:          "Failure: tunnel not started",
+			args:          args{remoteAddr: "example.com:443"},
+			wantErr:       true,
+			tunnelStopped: true,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -407,6 +432,10 @@ func TestPsiphonTunnel_Dial(t *testing.T) {
 			}
 			defer tunnel.Stop()
 
+			if tt.tunnelStopped {
+				tunnel.Stop()
+			}
+
 			conn, err := tunnel.Dial(tt.args.remoteAddr)
 			if (err != nil) != tt.wantErr {
 				t.Fatalf("PsiphonTunnel.Dial() error = %v, wantErr %v", err, tt.wantErr)
@@ -423,18 +452,6 @@ func TestPsiphonTunnel_Dial(t *testing.T) {
 // We had a problem where config-related notices were being printed to stderr before we
 // set the NoticeWriter. We want to make sure that no longer happens.
 func TestStartTunnelNoOutput(t *testing.T) {
-	configJSON, err := os.ReadFile("../../psiphon/controller_test.config")
-	if err != nil {
-		// What to do if config file is not present?
-		t.Skipf("error loading configuration file: %s", err)
-	}
-
-	var config map[string]interface{}
-	err = json.Unmarshal(configJSON, &config)
-	if err != nil {
-		t.Fatalf("json.Unmarshal failed: %v", err)
-	}
-
 	// Before starting the tunnel, set up a notice receiver. If it receives anything at
 	// all, that means that it would have been printed to stderr.
 	psiphon.SetNoticeWriter(psiphon.NewNoticeReceiver(
@@ -442,14 +459,7 @@ func TestStartTunnelNoOutput(t *testing.T) {
 			t.Fatalf("Received notice: %v", string(notice))
 		}))
 
-	// Use the legacy encoding to both exercise that case, and facilitate a
-	// gradual network upgrade to new encoding support.
-	config["TargetAPIEncoding"] = protocol.PSIPHON_API_ENCODING_JSON
-
-	configJSON, err = json.Marshal(config)
-	if err != nil {
-		t.Fatalf("json.Marshal failed: %v", err)
-	}
+	configJSON := setupConfig(t, false)
 
 	testDataDirName, err := os.MkdirTemp("", "psiphon-clientlib-test")
 	if err != nil {
@@ -499,26 +509,7 @@ func TestStartTunnelReentry(t *testing.T) {
 	}
 
 	// Call again with a good config. Should work.
-	configJSON, err = os.ReadFile("../../psiphon/controller_test.config")
-	if err != nil {
-		// What to do if config file is not present?
-		t.Skipf("error loading configuration file: %s", err)
-	}
-
-	var config map[string]interface{}
-	err = json.Unmarshal(configJSON, &config)
-	if err != nil {
-		t.Fatalf("json.Unmarshal failed: %v", err)
-	}
-
-	// Use the legacy encoding to both exercise that case, and facilitate a
-	// gradual network upgrade to new encoding support.
-	config["TargetAPIEncoding"] = protocol.PSIPHON_API_ENCODING_JSON
-
-	configJSON, err = json.Marshal(config)
-	if err != nil {
-		t.Fatalf("json.Marshal failed: %v", err)
-	}
+	configJSON = setupConfig(t, false)
 
 	tunnel, err := StartTunnel(
 		ctx,