github.com/enbility/spine-go@v0.7.0/integration_tests/helper_test.go (about)

     1  package integrationtests
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  	"sync"
     8  	"testing"
     9  	"time"
    10  
    11  	shipapi "github.com/enbility/ship-go/api"
    12  	"github.com/enbility/spine-go/api"
    13  	"github.com/enbility/spine-go/model"
    14  	"github.com/enbility/spine-go/spine"
    15  )
    16  
    17  const (
    18  	wallbox_detaileddiscoverydata_recv_reply_file_path  = "../spine/testdata/wallbox_detaileddiscoverydata_recv_reply.json"
    19  	wallbox_detaileddiscoverydata_recv_notify_file_path = "../spine/testdata/wallbox_detaileddiscoverydata_recv_notify.json"
    20  )
    21  
    22  type WriteMessageHandler struct {
    23  	sentMessages [][]byte
    24  
    25  	mux sync.Mutex
    26  }
    27  
    28  var _ shipapi.ShipConnectionDataWriterInterface = (*WriteMessageHandler)(nil)
    29  
    30  func (t *WriteMessageHandler) WriteShipMessageWithPayload(message []byte) {
    31  	t.mux.Lock()
    32  	defer t.mux.Unlock()
    33  
    34  	t.sentMessages = append(t.sentMessages, message)
    35  }
    36  
    37  func (t *WriteMessageHandler) LastMessage() []byte {
    38  	t.mux.Lock()
    39  	defer t.mux.Unlock()
    40  
    41  	if len(t.sentMessages) == 0 {
    42  		return nil
    43  	}
    44  
    45  	return t.sentMessages[len(t.sentMessages)-1]
    46  }
    47  
    48  func (t *WriteMessageHandler) MessageWithReference(msgCounterReference *model.MsgCounterType) []byte {
    49  	t.mux.Lock()
    50  	defer t.mux.Unlock()
    51  
    52  	var datagram model.Datagram
    53  
    54  	for _, msg := range t.sentMessages {
    55  		if err := json.Unmarshal(msg, &datagram); err != nil {
    56  			return nil
    57  		}
    58  		if datagram.Datagram.Header.MsgCounterReference == nil {
    59  			continue
    60  		}
    61  		if uint(*datagram.Datagram.Header.MsgCounterReference) != uint(*msgCounterReference) {
    62  			continue
    63  		}
    64  		if datagram.Datagram.Payload.Cmd[0].ResultData != nil {
    65  			continue
    66  		}
    67  
    68  		return msg
    69  	}
    70  
    71  	return nil
    72  }
    73  
    74  func (t *WriteMessageHandler) ResultWithReference(msgCounterReference *model.MsgCounterType) []byte {
    75  	t.mux.Lock()
    76  	defer t.mux.Unlock()
    77  
    78  	var datagram model.Datagram
    79  
    80  	for _, msg := range t.sentMessages {
    81  		if err := json.Unmarshal(msg, &datagram); err != nil {
    82  			return nil
    83  		}
    84  		if datagram.Datagram.Header.MsgCounterReference == nil {
    85  			continue
    86  		}
    87  		if uint(*datagram.Datagram.Header.MsgCounterReference) != uint(*msgCounterReference) {
    88  			continue
    89  		}
    90  		if datagram.Datagram.Payload.Cmd[0].ResultData == nil {
    91  			continue
    92  		}
    93  
    94  		return msg
    95  	}
    96  
    97  	return nil
    98  }
    99  
   100  func beforeTest(
   101  	fId uint, ftype model.FeatureTypeType,
   102  	frole model.RoleType) (api.DeviceLocalInterface, string, api.DeviceRemoteInterface, *WriteMessageHandler) {
   103  	sut := spine.NewDeviceLocal("TestBrandName", "TestDeviceModel", "TestSerialNumber", "TestDeviceCode",
   104  		"TestDeviceAddress", model.DeviceTypeTypeEnergyManagementSystem, model.NetworkManagementFeatureSetTypeSmart)
   105  	localEntity := spine.NewEntityLocal(sut, model.EntityTypeTypeCEM, spine.NewAddressEntityType([]uint{1}), time.Second*4)
   106  	sut.AddEntity(localEntity)
   107  	f := spine.NewFeatureLocal(fId, localEntity, ftype, frole)
   108  	localEntity.AddFeature(f)
   109  
   110  	remoteSki := "TestRemoteSki"
   111  
   112  	writeHandler := &WriteMessageHandler{}
   113  	_ = sut.SetupRemoteDevice(remoteSki, writeHandler)
   114  	remoteDevice := sut.RemoteDeviceForSki(remoteSki)
   115  
   116  	return sut, remoteSki, remoteDevice, writeHandler
   117  }
   118  
   119  func initialCommunication(t *testing.T, remoteDevice api.DeviceRemoteInterface, writeHandler *WriteMessageHandler) {
   120  	// Initial generic communication
   121  
   122  	_, _ = remoteDevice.HandleSpineMesssage(loadFileData(t, wallbox_detaileddiscoverydata_recv_reply_file_path))
   123  
   124  	// Act
   125  	msgCounter, _ := remoteDevice.HandleSpineMesssage(loadFileData(t, wallbox_detaileddiscoverydata_recv_notify_file_path))
   126  	waitForAck(t, msgCounter, writeHandler)
   127  }
   128  
   129  func loadFileData(t *testing.T, fileName string) []byte {
   130  	fileData, err := os.ReadFile(fileName) // #nosec G304
   131  	if err != nil {
   132  		t.Fatal(err)
   133  	}
   134  
   135  	return fileData
   136  }
   137  
   138  func waitForAck(t *testing.T, msgCounterReference *model.MsgCounterType, writeHandler *WriteMessageHandler) {
   139  	var datagram model.Datagram
   140  
   141  	msg := writeHandler.ResultWithReference(msgCounterReference)
   142  	if msg == nil {
   143  		t.Fatal("acknowledge message was not sent!!")
   144  	}
   145  
   146  	if err := json.Unmarshal(msg, &datagram); err != nil {
   147  		t.Fatal(err)
   148  	}
   149  
   150  	cmd := datagram.Datagram.Payload.Cmd[0]
   151  	if cmd.ResultData != nil {
   152  		if cmd.ResultData.ErrorNumber != nil && uint(*cmd.ResultData.ErrorNumber) != uint(model.ErrorNumberTypeNoError) {
   153  			t.Fatal(fmt.Errorf("error '%d' result data received", uint(*cmd.ResultData.ErrorNumber)))
   154  		}
   155  	}
   156  }