421 lines
10 KiB
Go
421 lines
10 KiB
Go
package websocket
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
m "github.com/fiskerinc/cloud-services/pkg/common"
|
|
"github.com/fiskerinc/cloud-services/pkg/httpclient"
|
|
"github.com/fiskerinc/cloud-services/pkg/httpclient/mock"
|
|
kafka "github.com/fiskerinc/cloud-services/pkg/kafka/mock"
|
|
"github.com/fiskerinc/cloud-services/pkg/testhelper"
|
|
|
|
"github.com/gobwas/httphead"
|
|
"github.com/gobwas/ws"
|
|
"github.com/gobwas/ws/wsutil"
|
|
)
|
|
|
|
func createMockWebsocketClient(url, userAgent string) net.Conn {
|
|
u := "ws" + strings.TrimPrefix(url, "http")
|
|
|
|
header := make(http.Header)
|
|
header.Add("User-Agent", userAgent)
|
|
header.Add("X-ICCID", "12345678912345678923456789")
|
|
header.Add("Ssl-Client-Subject-Dn", "CN=1F15K3R45N1234567")
|
|
dialer := ws.Dialer{
|
|
Header: ws.HandshakeHeaderHTTP(header),
|
|
Extensions: []httphead.Option{httphead.NewOption("permessage-deflate", map[string]string{})},
|
|
}
|
|
|
|
ctx := context.Background()
|
|
ws, _, _, err := dialer.Dial(ctx, u)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return ws
|
|
}
|
|
|
|
func TestSecureSessionTRex(t *testing.T) {
|
|
userAgent := "Fisker Ocean T.Rex 1.2.3.4 abc123"
|
|
|
|
createNewSession := func(w http.ResponseWriter, r *http.Request) {
|
|
s, err := NewSecureSession(w, r)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestNewSessionTRex", nil, err)
|
|
}
|
|
defer s.Close()
|
|
|
|
if fmt.Sprintf("%T", s) != "*websocket.SessionTRex" {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestNewSessionTRex", "*websocket.SessionTRex", fmt.Sprintf("%T", s))
|
|
}
|
|
}
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(createNewSession))
|
|
defer server.Close()
|
|
|
|
conn := createMockWebsocketClient(server.URL, userAgent)
|
|
defer conn.Close()
|
|
}
|
|
|
|
func TestSecureSessionHMI(t *testing.T) {
|
|
userAgent := "HMI 2.0.0.0"
|
|
|
|
createNewSession := func(w http.ResponseWriter, r *http.Request) {
|
|
s, err := NewSecureSession(w, r)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestNewSessionHMI", nil, err)
|
|
}
|
|
defer s.Close()
|
|
|
|
if fmt.Sprintf("%T", s) != "*websocket.SessionHMI" {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestNewSessionHMI", "*websocket.SessionHMI", fmt.Sprintf("%T", s))
|
|
}
|
|
}
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(createNewSession))
|
|
defer server.Close()
|
|
|
|
conn := createMockWebsocketClient(server.URL, userAgent)
|
|
defer conn.Close()
|
|
}
|
|
|
|
func TestInsecureSessionMobile(t *testing.T) {
|
|
userAgent := "Mobile 1.2.3.4"
|
|
|
|
createNewSession := func(w http.ResponseWriter, r *http.Request) {
|
|
s, err := NewInsecureSession(w, r)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestNewSessionMobile", nil, err)
|
|
}
|
|
defer s.Close()
|
|
|
|
if fmt.Sprintf("%T", s) != "*websocket.SessionMobile" {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestNewSessionMobile", "*websocket.SessionMobile", fmt.Sprintf("%T", s))
|
|
}
|
|
}
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(createNewSession))
|
|
defer server.Close()
|
|
|
|
conn := createMockWebsocketClient(server.URL, userAgent)
|
|
defer conn.Close()
|
|
}
|
|
|
|
func TestSession(t *testing.T) {
|
|
ws, _ := net.Pipe()
|
|
s := &Session{
|
|
Websocket: ws,
|
|
}
|
|
|
|
if fmt.Sprintf("%T", s) != "*websocket.Session" {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSession", "*websocket.Session", fmt.Sprintf("%T", s))
|
|
}
|
|
}
|
|
|
|
func TestNewSession(t *testing.T) {
|
|
userAgent := ""
|
|
|
|
createNewSession := func(w http.ResponseWriter, r *http.Request) {
|
|
s, err := NewSession(w, r)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestNewSession", nil, err)
|
|
}
|
|
defer s.Close()
|
|
|
|
if fmt.Sprintf("%T", s) != "*websocket.Session" {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestNewSession", "*websocket.Session", fmt.Sprintf("%T", s))
|
|
}
|
|
}
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(createNewSession))
|
|
defer server.Close()
|
|
|
|
conn := createMockWebsocketClient(server.URL, userAgent)
|
|
defer conn.Close()
|
|
}
|
|
|
|
func TestSessionAuthenticate(t *testing.T) {
|
|
c := mock.Client{
|
|
DoFunc: func(*http.Request) (*http.Response, error) {
|
|
return &http.Response{StatusCode: 200}, nil
|
|
},
|
|
}
|
|
httpclient.Client = &c
|
|
userAgent := ""
|
|
|
|
createNewSession := func(w http.ResponseWriter, r *http.Request) {
|
|
s, err := NewSession(w, r)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionAuthenticate", nil, err)
|
|
}
|
|
defer s.Close()
|
|
|
|
err = s.Authenticate()
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionAuthenticate", nil, err)
|
|
}
|
|
}
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(createNewSession))
|
|
defer server.Close()
|
|
|
|
conn := createMockWebsocketClient(server.URL, userAgent)
|
|
defer conn.Close()
|
|
|
|
ae := AuthEvent{
|
|
Topic: "auth_service",
|
|
Key: "FISKER123",
|
|
Payload: AuthPayload{
|
|
Handler: "verify",
|
|
Data: AuthData{
|
|
Token: "validtoken",
|
|
},
|
|
},
|
|
}
|
|
|
|
msg, err := json.Marshal(ae)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionAuthenticate", nil, err)
|
|
}
|
|
|
|
wsutil.WriteClientMessage(conn, ws.OpText, msg)
|
|
}
|
|
|
|
func TestSessionKey(t *testing.T) {
|
|
ws, _ := net.Pipe()
|
|
s := &Session{
|
|
Websocket: ws,
|
|
Type: m.TRex,
|
|
ID: "FISKER123",
|
|
}
|
|
|
|
key := s.Key()
|
|
if key != "1:FISKER123" {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionKey", "1:FISKER123", key)
|
|
}
|
|
}
|
|
|
|
func TestSessionKeyUnknown(t *testing.T) {
|
|
ws, _ := net.Pipe()
|
|
s := &Session{
|
|
Websocket: ws,
|
|
Type: m.Unknown,
|
|
ID: "FISKER123",
|
|
}
|
|
|
|
key := s.Key()
|
|
if key != "FISKER123" {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionKeyUnknown", "FISKER123", key)
|
|
}
|
|
}
|
|
|
|
func TestSessionReceive(t *testing.T) {
|
|
userAgent := ""
|
|
payload := "hello fisker!"
|
|
|
|
createNewSession := func(w http.ResponseWriter, r *http.Request) {
|
|
s, err := NewSession(w, r)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionReceive", nil, err)
|
|
}
|
|
defer s.Close()
|
|
|
|
data, _, err := s.Receive()
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionReceive", nil, err)
|
|
}
|
|
|
|
msg := string(data)
|
|
if msg != payload {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionReceive", payload, msg)
|
|
}
|
|
}
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(createNewSession))
|
|
defer server.Close()
|
|
|
|
conn := createMockWebsocketClient(server.URL, userAgent)
|
|
defer conn.Close()
|
|
|
|
err := wsutil.WriteClientMessage(conn, ws.OpText, []byte(payload))
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionReceive", nil, err)
|
|
}
|
|
}
|
|
|
|
func TestSessionListen(t *testing.T) {
|
|
userAgent := ""
|
|
payload := "hello fisker!"
|
|
|
|
createNewSession := func(w http.ResponseWriter, r *http.Request) {
|
|
s, err := NewSession(w, r)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionListen", nil, err)
|
|
}
|
|
defer s.Close()
|
|
|
|
ctx := context.Background()
|
|
err = s.Listen(ctx, kafka.GetKafkaMock(nil))
|
|
if err.Error() != "EOF" {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionListen", nil, err)
|
|
}
|
|
}
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(createNewSession))
|
|
defer server.Close()
|
|
|
|
conn := createMockWebsocketClient(server.URL, userAgent)
|
|
defer conn.Close()
|
|
|
|
err := wsutil.WriteClientMessage(conn, ws.OpText, []byte(payload))
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionListen", nil, err)
|
|
}
|
|
}
|
|
|
|
func TestSessionSend(t *testing.T) {
|
|
userAgent := ""
|
|
payload := "hello fisker!"
|
|
|
|
createNewSession := func(w http.ResponseWriter, r *http.Request) {
|
|
s, err := NewSession(w, r)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionSend", nil, err)
|
|
}
|
|
defer s.Close()
|
|
|
|
data, _, err := s.Receive()
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionSend", nil, err)
|
|
}
|
|
|
|
msg := string(data)
|
|
if msg != payload {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionSend", payload, msg)
|
|
}
|
|
|
|
err = s.SendMsgToClient(data)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionSend", nil, err)
|
|
}
|
|
}
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(createNewSession))
|
|
defer server.Close()
|
|
|
|
conn := createMockWebsocketClient(server.URL, userAgent)
|
|
defer conn.Close()
|
|
|
|
err := wsutil.WriteClientMessage(conn, ws.OpText, []byte(payload))
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionSend", nil, err)
|
|
}
|
|
|
|
echo, _, err := wsutil.ReadServerData(conn)
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionSend", nil, err)
|
|
}
|
|
|
|
message := string(echo)
|
|
if message != payload {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionSend", payload, message)
|
|
}
|
|
}
|
|
|
|
func TestSessionLoad(t *testing.T) {
|
|
ws, _ := net.Pipe()
|
|
s := &Session{
|
|
Websocket: ws,
|
|
Type: m.TRex,
|
|
ID: "FISKER123",
|
|
}
|
|
|
|
err := s.Load(kafka.GetKafkaMock(nil))
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionLoad", nil, err)
|
|
}
|
|
}
|
|
|
|
func TestSessionTeardown(t *testing.T) {
|
|
ws, _ := net.Pipe()
|
|
s := &Session{
|
|
Websocket: ws,
|
|
Type: m.TRex,
|
|
ID: "FISKER123",
|
|
}
|
|
|
|
err := s.Load(kafka.GetKafkaMock(nil))
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionLoad", nil, err)
|
|
}
|
|
|
|
err = s.Teardown(kafka.GetKafkaMock(nil))
|
|
if err != nil {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionLoad", nil, err)
|
|
}
|
|
}
|
|
|
|
func TestSessionGetUUID(t *testing.T) {
|
|
ws, _ := net.Pipe()
|
|
currentNanoSeconds := time.Now().UnixNano()
|
|
s := &Session{
|
|
Websocket: ws,
|
|
Type: m.TRex,
|
|
ID: "FISKER123",
|
|
epoch: currentNanoSeconds,
|
|
}
|
|
|
|
uuid := s.GetUUID()
|
|
if uuid != currentNanoSeconds {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionLoad", currentNanoSeconds, uuid)
|
|
}
|
|
}
|
|
|
|
type SessionGetVINTestCase struct {
|
|
Name string
|
|
Session *Session
|
|
VIN string
|
|
ExpectedErrorMsg string
|
|
}
|
|
|
|
func TestSessionGetVIN(t *testing.T) {
|
|
ws, _ := net.Pipe()
|
|
|
|
tests := []SessionGetVINTestCase{
|
|
{
|
|
Name: "Parsable",
|
|
Session: &Session{
|
|
Websocket: ws,
|
|
Type: m.TRex,
|
|
ID: "VCF1EBU22PG001732",
|
|
},
|
|
VIN: "VCF1EBU22PG001732",
|
|
},
|
|
{
|
|
Name: "Not Parsable",
|
|
Session: &Session{
|
|
Websocket: ws,
|
|
Type: m.TRex,
|
|
ID: "FISKER123",
|
|
},
|
|
VIN: "FISKER123",
|
|
ExpectedErrorMsg: "could not get VIN from session",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
vin := tt.Session.GetID()
|
|
|
|
if vin != tt.VIN {
|
|
t.Errorf(testhelper.TestErrorTemplate, "TestSessionGetVIN", tt.VIN, vin)
|
|
}
|
|
}
|
|
}
|