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

     1  package spine
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/enbility/spine-go/api"
     8  	"github.com/enbility/spine-go/model"
     9  	"github.com/enbility/spine-go/util"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/suite"
    12  )
    13  
    14  func TestHeartbeatManagerSuite(t *testing.T) {
    15  	suite.Run(t, new(HeartBeatManagerSuite))
    16  }
    17  
    18  type HeartBeatManagerSuite struct {
    19  	suite.Suite
    20  
    21  	localDevice api.DeviceLocalInterface
    22  	localEntity api.EntityLocalInterface
    23  
    24  	remoteDevice api.DeviceRemoteInterface
    25  	sut          api.HeartbeatManagerInterface
    26  }
    27  
    28  func (s *HeartBeatManagerSuite) WriteShipMessageWithPayload([]byte) {}
    29  
    30  func (s *HeartBeatManagerSuite) BeforeTest(suiteName, testName string) {
    31  	s.localDevice = NewDeviceLocal("brand", "model", "serial", "code", "address", model.DeviceTypeTypeEnergyManagementSystem, model.NetworkManagementFeatureSetTypeSmart)
    32  	s.localEntity = NewEntityLocal(s.localDevice, model.EntityTypeTypeCEM, []model.AddressEntityType{1}, time.Second*4)
    33  	s.localDevice.AddEntity(s.localEntity)
    34  
    35  	ski := "test"
    36  	sender := NewSender(s)
    37  	s.remoteDevice = NewDeviceRemote(s.localDevice, ski, sender)
    38  
    39  	_ = s.localDevice.SetupRemoteDevice(ski, s)
    40  
    41  	s.sut = s.localEntity.HeartbeatManager()
    42  }
    43  
    44  func (s *HeartBeatManagerSuite) Test_HeartbeatFailure() {
    45  	s.sut.SetLocalFeature(nil, nil)
    46  
    47  	localFeature := s.localEntity.GetOrAddFeature(model.FeatureTypeTypeDeviceConfiguration, model.RoleTypeServer)
    48  	s.localEntity.AddFeature(localFeature)
    49  
    50  	s.sut.SetLocalFeature(s.localEntity, localFeature)
    51  
    52  	running := s.sut.IsHeartbeatRunning()
    53  	assert.Equal(s.T(), false, running)
    54  
    55  	anotherFeature := s.localEntity.GetOrAddFeature(model.FeatureTypeTypeDeviceDiagnosis, model.RoleTypeServer)
    56  	s.localEntity.AddFeature(anotherFeature)
    57  
    58  	s.sut.SetLocalFeature(s.localEntity, anotherFeature)
    59  
    60  	running = s.sut.IsHeartbeatRunning()
    61  	assert.Equal(s.T(), false, running)
    62  
    63  	anotherFeature.AddFunctionType(model.FunctionTypeDeviceDiagnosisHeartbeatData, true, false)
    64  
    65  	s.sut.SetLocalFeature(s.localEntity, anotherFeature)
    66  
    67  	running = s.sut.IsHeartbeatRunning()
    68  	assert.Equal(s.T(), true, running)
    69  }
    70  
    71  func (s *HeartBeatManagerSuite) Test_HeartbeatSuccess() {
    72  	localFeature := s.localEntity.GetOrAddFeature(model.FeatureTypeTypeDeviceDiagnosis, model.RoleTypeServer)
    73  	localFeature.AddFunctionType(model.FunctionTypeDeviceDiagnosisHeartbeatData, false, false)
    74  	s.localEntity.AddFeature(localFeature)
    75  
    76  	s.sut.SetLocalFeature(s.localEntity, localFeature)
    77  
    78  	remoteEntity := NewEntityRemote(s.remoteDevice, model.EntityTypeTypeEVSE, []model.AddressEntityType{1})
    79  	s.remoteDevice.AddEntity(remoteEntity)
    80  
    81  	remoteFeature := NewFeatureRemote(remoteEntity.NextFeatureId(), remoteEntity, model.FeatureTypeTypeDeviceDiagnosis, model.RoleTypeClient)
    82  	remoteEntity.AddFeature(remoteFeature)
    83  
    84  	subscrRequest := &model.SubscriptionManagementRequestCallType{
    85  		ClientAddress:     remoteFeature.Address(),
    86  		ServerAddress:     localFeature.Address(),
    87  		ServerFeatureType: util.Ptr(model.FeatureTypeTypeDeviceDiagnosis),
    88  	}
    89  
    90  	datagram := model.DatagramType{
    91  		Header: model.HeaderType{
    92  			SpecificationVersion: &SpecificationVersion,
    93  			AddressSource: &model.FeatureAddressType{
    94  				Device:  s.remoteDevice.Address(),
    95  				Entity:  []model.AddressEntityType{0},
    96  				Feature: util.Ptr(model.AddressFeatureType(0)),
    97  			},
    98  			AddressDestination: &model.FeatureAddressType{
    99  				Device:  s.localDevice.Address(),
   100  				Entity:  []model.AddressEntityType{0},
   101  				Feature: util.Ptr(model.AddressFeatureType(0)),
   102  			},
   103  			MsgCounter:    util.Ptr(model.MsgCounterType(1000)),
   104  			CmdClassifier: util.Ptr(model.CmdClassifierTypeCall),
   105  		},
   106  		Payload: model.PayloadType{
   107  			Cmd: []model.CmdType{
   108  				{
   109  					NodeManagementSubscriptionRequestCall: &model.NodeManagementSubscriptionRequestCallType{
   110  						SubscriptionRequest: subscrRequest,
   111  					},
   112  				},
   113  			},
   114  		},
   115  	}
   116  	err := s.localDevice.ProcessCmd(datagram, s.remoteDevice)
   117  	assert.Nil(s.T(), err)
   118  
   119  	data := localFeature.DataCopy(model.FunctionTypeDeviceDiagnosisHeartbeatData)
   120  	assert.Nil(s.T(), data)
   121  
   122  	running := s.sut.IsHeartbeatRunning()
   123  	assert.Equal(s.T(), false, running)
   124  
   125  	s.localDevice.RemoveEntity(s.localEntity)
   126  	s.localEntity = NewEntityLocal(s.localDevice, model.EntityTypeTypeCEM, []model.AddressEntityType{1}, time.Second*4)
   127  	s.localDevice.AddEntity(s.localEntity)
   128  
   129  	localFeature = s.localEntity.GetOrAddFeature(model.FeatureTypeTypeDeviceDiagnosis, model.RoleTypeServer)
   130  	localFeature.AddFunctionType(model.FunctionTypeDeviceDiagnosisHeartbeatData, true, false)
   131  	s.localEntity.AddFeature(localFeature)
   132  
   133  	s.sut.SetLocalFeature(s.localEntity, localFeature)
   134  
   135  	err = s.localDevice.ProcessCmd(datagram, s.remoteDevice)
   136  	assert.Nil(s.T(), err)
   137  
   138  	time.Sleep(time.Second * 5)
   139  
   140  	running = s.sut.IsHeartbeatRunning()
   141  	assert.Equal(s.T(), true, running)
   142  
   143  	data = localFeature.DataCopy(model.FunctionTypeDeviceDiagnosisHeartbeatData)
   144  	assert.NotNil(s.T(), data)
   145  
   146  	fctData := data.(*model.DeviceDiagnosisHeartbeatDataType)
   147  	var resultCounter uint64 = 1
   148  	assert.LessOrEqual(s.T(), resultCounter, *fctData.HeartbeatCounter)
   149  	resultTimeout, err := fctData.HeartbeatTimeout.GetTimeDuration()
   150  	assert.Nil(s.T(), err)
   151  	assert.Equal(s.T(), time.Second*4, resultTimeout)
   152  
   153  	subscrDelRequest := &model.SubscriptionManagementDeleteCallType{
   154  		ClientAddress: remoteFeature.Address(),
   155  		ServerAddress: localFeature.Address(),
   156  	}
   157  
   158  	datagram.Payload = model.PayloadType{
   159  		Cmd: []model.CmdType{
   160  			{
   161  				NodeManagementSubscriptionDeleteCall: &model.NodeManagementSubscriptionDeleteCallType{
   162  					SubscriptionDelete: subscrDelRequest,
   163  				},
   164  			},
   165  		},
   166  	}
   167  
   168  	err = s.localDevice.ProcessCmd(datagram, s.remoteDevice)
   169  	assert.Nil(s.T(), err)
   170  
   171  	isHeartbeatRunning := s.sut.IsHeartbeatRunning()
   172  	assert.Equal(s.T(), true, isHeartbeatRunning)
   173  
   174  	s.sut.StopHeartbeat()
   175  
   176  	isHeartbeatRunning = s.sut.IsHeartbeatRunning()
   177  	assert.Equal(s.T(), false, isHeartbeatRunning)
   178  }