github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/core/service/manager_test.go (about) 1 /* 2 * Copyright (C) 2019 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package service 19 20 import ( 21 "errors" 22 "testing" 23 "time" 24 25 "github.com/mysteriumnetwork/node/core/policy/localcopy" 26 "github.com/mysteriumnetwork/node/core/policy/requested" 27 28 "github.com/mysteriumnetwork/node/core/location/locationstate" 29 "github.com/mysteriumnetwork/node/core/service/servicestate" 30 "github.com/mysteriumnetwork/node/identity" 31 "github.com/mysteriumnetwork/node/market" 32 "github.com/mysteriumnetwork/node/mocks" 33 "github.com/mysteriumnetwork/node/p2p" 34 "github.com/mysteriumnetwork/node/requests" 35 "github.com/mysteriumnetwork/node/utils/netutil" 36 "github.com/stretchr/testify/assert" 37 ) 38 39 var ( 40 serviceType = "the-very-awesome-test-service-type" 41 mockPolicyOracle = localcopy.NewOracle(requests.NewHTTPClient("0.0.0.0", requests.DefaultTimeout), "http://policy.localhost/", 1*time.Minute, true) 42 mockPolicyProvider = requested.NewRequestedProvider(requests.NewHTTPClient("0.0.0.0", requests.DefaultTimeout), "http://policy.localhost/") 43 ) 44 45 func init() { 46 netutil.LogNetworkStats = func() {} 47 } 48 49 func TestManager_StartRemovesServiceFromPoolIfServiceCrashes(t *testing.T) { 50 registry := NewRegistry() 51 mockCopy := *serviceMock 52 mockCopy.onStartReturnError = errors.New("some error") 53 registry.Register(serviceType, func(options Options) (Service, error) { 54 return &mockCopy, nil 55 }) 56 57 discovery := mockDiscovery{} 58 discoveryFactory := MockDiscoveryFactoryFunc(&discovery) 59 manager := NewManager( 60 registry, 61 discoveryFactory, 62 mocks.NewEventBus(), 63 mockPolicyOracle, 64 mockPolicyProvider, 65 &mockP2PListener{}, nil, nil, mockLocationResolver{}, 66 ) 67 _, err := manager.Start(identity.FromAddress(proposalMock.ProviderID), serviceType, nil, struct{}{}) 68 assert.Nil(t, err) 69 70 discovery.Wait() 71 assert.Len(t, manager.servicePool.List(), 0) 72 } 73 74 func TestManager_StartDoesNotCrashIfStoppedByUser(t *testing.T) { 75 registry := NewRegistry() 76 mockCopy := *serviceMock 77 mockCopy.mockProcess = make(chan struct{}) 78 registry.Register(serviceType, func(options Options) (Service, error) { 79 return &mockCopy, nil 80 }) 81 82 discovery := mockDiscovery{} 83 discoveryFactory := MockDiscoveryFactoryFunc(&discovery) 84 manager := NewManager( 85 registry, 86 discoveryFactory, 87 mocks.NewEventBus(), 88 mockPolicyOracle, 89 mockPolicyProvider, 90 &mockP2PListener{}, nil, nil, 91 mockLocationResolver{}, 92 ) 93 id, err := manager.Start(identity.FromAddress(proposalMock.ProviderID), serviceType, nil, struct{}{}) 94 assert.Nil(t, err) 95 err = manager.Stop(id) 96 assert.Nil(t, err) 97 discovery.Wait() 98 assert.Len(t, manager.servicePool.List(), 0) 99 } 100 101 func TestManager_StopSendsEvent_SucceedsAndPublishesEvent(t *testing.T) { 102 registry := NewRegistry() 103 mockCopy := *serviceMock 104 mockCopy.mockProcess = make(chan struct{}) 105 registry.Register(serviceType, func(options Options) (Service, error) { 106 return &mockCopy, nil 107 }) 108 109 discovery := mockDiscovery{} 110 discoveryFactory := MockDiscoveryFactoryFunc(&discovery) 111 eventBus := &mockPublisher{} 112 manager := NewManager( 113 registry, 114 discoveryFactory, 115 eventBus, 116 mockPolicyOracle, 117 mockPolicyProvider, 118 &mockP2PListener{}, nil, nil, 119 mockLocationResolver{}, 120 ) 121 122 id, err := manager.Start(identity.FromAddress(proposalMock.ProviderID), serviceType, nil, struct{}{}) 123 assert.NoError(t, err) 124 125 services := manager.servicePool.List() 126 127 var serviceID ID 128 for k := range services { 129 serviceID = services[k].ID 130 } 131 132 err = manager.Stop(id) 133 assert.NoError(t, err) 134 135 time.Sleep(time.Millisecond * 30) 136 137 eventBus.lock.Lock() 138 defer eventBus.lock.Unlock() 139 140 assert.Equal(t, servicestate.AppTopicServiceStatus, eventBus.publishedTopic) 141 142 var matchFound bool 143 expectedPayload := servicestate.AppEventServiceStatus{ID: string(serviceID), ProviderID: "", Type: "", Status: "NotRunning"} 144 for i := range eventBus.publishedData { 145 e, ok := eventBus.publishedData[i].(servicestate.AppEventServiceStatus) 146 if !ok { 147 continue 148 } 149 if e.Status == expectedPayload.Status && e.ID == expectedPayload.ID { 150 matchFound = true 151 break 152 } 153 } 154 assert.True(t, matchFound) 155 } 156 157 type mockP2PListener struct { 158 } 159 160 func (m mockP2PListener) GetContact() market.Contact { 161 return market.Contact{} 162 } 163 164 func (m mockP2PListener) Listen(_ identity.Identity, serviceType string, channelHandler func(ch p2p.Channel)) (func(), error) { 165 return func() {}, nil 166 } 167 168 type mockLocationResolver struct { 169 } 170 171 func (m mockLocationResolver) DetectLocation() (locationstate.Location, error) { 172 return locationstate.Location{}, nil 173 }