github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/services/wireguard/service/service_test.go (about) 1 /* 2 * Copyright (C) 2018 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 "net" 22 "sync" 23 "testing" 24 "time" 25 26 "github.com/stretchr/testify/assert" 27 28 "github.com/mysteriumnetwork/node/core/ip" 29 "github.com/mysteriumnetwork/node/core/policy/localcopy" 30 "github.com/mysteriumnetwork/node/core/service" 31 "github.com/mysteriumnetwork/node/core/service/servicestate" 32 "github.com/mysteriumnetwork/node/dns" 33 "github.com/mysteriumnetwork/node/identity" 34 "github.com/mysteriumnetwork/node/market" 35 "github.com/mysteriumnetwork/node/nat" 36 wg "github.com/mysteriumnetwork/node/services/wireguard" 37 "github.com/mysteriumnetwork/node/services/wireguard/wgcfg" 38 ) 39 40 var ( 41 pubIP = "127.0.0.1" 42 outIP = "127.0.0.1" 43 country = "LT" 44 ) 45 46 var connectionEndpointStub = &mockConnectionEndpoint{} 47 48 func Test_Manager_Stop(t *testing.T) { 49 manager := newManagerStub(pubIP, outIP, country) 50 51 service := service.NewInstance( 52 identity.FromAddress("0x1"), 53 "", 54 nil, 55 market.ServiceProposal{}, 56 servicestate.Running, 57 nil, 58 localcopy.NewRepository(), 59 nil, 60 ) 61 62 go func() { 63 err := manager.Serve(service) 64 assert.NoError(t, err) 65 }() 66 67 waitABit() 68 err := manager.Stop() 69 assert.NoError(t, err) 70 } 71 72 func Test_Manager_Stop_Datarace(t *testing.T) { 73 manager := newManagerStub(pubIP, outIP, country) 74 75 service := service.NewInstance( 76 identity.FromAddress("0x1"), 77 "", 78 nil, 79 market.ServiceProposal{}, 80 servicestate.Running, 81 nil, 82 localcopy.NewRepository(), 83 nil, 84 ) 85 manager.sessionCleanup = make(map[string]func()) 86 87 destroyClosure := func(sessionID string) func() { 88 return func() { 89 manager.sessionCleanupMu.Lock() 90 defer manager.sessionCleanupMu.Unlock() 91 92 _, ok := manager.sessionCleanup[sessionID] 93 if !ok { 94 return 95 } 96 delete(manager.sessionCleanup, sessionID) 97 } 98 } 99 100 var wg sync.WaitGroup 101 102 wg.Add(2) 103 go func() { 104 defer wg.Done() 105 err := manager.Serve(service) 106 assert.NoError(t, err) 107 }() 108 109 // normally the ProvideConfig() sets a callback, but in unit test we have to do it ourselves 110 manager.sessionCleanupMu.Lock() 111 manager.sessionCleanup["1"] = destroyClosure("1") 112 manager.sessionCleanupMu.Unlock() 113 114 waitABit() 115 go func() { 116 defer wg.Done() 117 err := manager.Stop() 118 assert.NoError(t, err) 119 }() 120 wg.Wait() 121 } 122 123 func Test_Manager_ProviderConfig_FailsWhenSessionConfigIsInvalid(t *testing.T) { 124 manager := newManagerStub(pubIP, outIP, country) 125 126 params, err := manager.ProvideConfig("", nil, nil) 127 128 assert.Nil(t, params) 129 assert.Error(t, err) 130 } 131 132 // usually time.Sleep call gives a chance for other goroutines to kick in important when testing async code 133 func waitABit() { 134 time.Sleep(10 * time.Millisecond) 135 } 136 137 type mockConnectionEndpoint struct{} 138 139 func (mce *mockConnectionEndpoint) StartConsumerMode(config wgcfg.DeviceConfig) error { return nil } 140 func (mce *mockConnectionEndpoint) ReconfigureConsumerMode(config wgcfg.DeviceConfig) error { 141 return nil 142 } 143 144 func (mce *mockConnectionEndpoint) StartProviderMode(ip string, config wgcfg.DeviceConfig) error { 145 return nil 146 } 147 func (mce *mockConnectionEndpoint) InterfaceName() string { return "mce0" } 148 func (mce *mockConnectionEndpoint) Stop() error { return nil } 149 func (mce *mockConnectionEndpoint) Config() (wg.ServiceConfig, error) { return wg.ServiceConfig{}, nil } 150 func (mce *mockConnectionEndpoint) AddPeer(_ string, _ wgcfg.Peer) error { return nil } 151 func (mce *mockConnectionEndpoint) RemovePeer(_ string) error { return nil } 152 func (mce *mockConnectionEndpoint) ConfigureRoutes(_ net.IP) error { return nil } 153 func (mce *mockConnectionEndpoint) PeerStats() (wgcfg.Stats, error) { 154 return wgcfg.Stats{LastHandshake: time.Now()}, nil 155 } 156 157 func newManagerStub(pub, out, country string) *Manager { 158 dnsHandler, _ := dns.ResolveViaSystem() 159 160 return &Manager{ 161 done: make(chan struct{}), 162 ipResolver: ip.NewResolverMock("1.2.3.4"), 163 natService: &serviceFake{}, 164 connEndpointFactory: func() (wg.ConnectionEndpoint, error) { 165 return connectionEndpointStub, nil 166 }, 167 dnsProxy: dns.NewProxy("", 0, dnsHandler), 168 } 169 } 170 171 type serviceFake struct{} 172 173 func (service *serviceFake) Setup(nat.Options) (rules []interface{}, err error) { 174 return nil, nil 175 } 176 func (service *serviceFake) Del([]interface{}) error { return nil } 177 func (service *serviceFake) Enable() error { return nil } 178 func (service *serviceFake) Disable() error { return nil }