Files

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)
}
}
}