github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/nat/service_ics_test.go (about) 1 //go:build windows 2 3 /* 4 * Copyright (C) 2019 The "MysteriumNetwork/node" Authors. 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package nat 21 22 import ( 23 "errors" 24 "net" 25 "strconv" 26 "testing" 27 28 "github.com/stretchr/testify/assert" 29 ) 30 31 var _ NATService = &serviceICS{} 32 33 func mockedICS(powerShell func(cmd string) ([]byte, error)) *serviceICS { 34 return &serviceICS{ 35 powerShell: powerShell, 36 setICSAddresses: mockICSConfig, 37 } 38 } 39 40 func Test_errorOnGetPublicInterfaceName(t *testing.T) { 41 sh := mockPowerShell{err: errors.New("expected error")} 42 ics := mockedICS(sh.exec) 43 _, err := ics.getPublicInterfaceName() 44 assert.EqualError(t, err, "failed to get interface from the default route: expected error") 45 } 46 47 func Test_parseErrorOnGetPublicInterfaceName(t *testing.T) { 48 sh := mockPowerShell{} 49 ics := mockedICS(sh.exec) 50 _, err := ics.getPublicInterfaceName() 51 assert.EqualError(t, err, "failed to parse interface ID: strconv.Atoi: parsing \"\": invalid syntax") 52 } 53 54 func Test_getPublicInterfaceName(t *testing.T) { 55 sh := mockPowerShell{commands: map[string]mockShellResult{ 56 "Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {[]byte("1234567890"), nil}, 57 }} 58 ics := mockedICS(sh.exec) 59 _, err := ics.getPublicInterfaceName() 60 assert.EqualError(t, err, "interface not found") 61 } 62 63 func Test_errorGettingServiceStartTypeOnEnable(t *testing.T) { 64 sh := mockPowerShell{commands: map[string]mockShellResult{ 65 "Get-Service RemoteAccess | foreach { $_.StartType }": {nil, errors.New("expected error")}, 66 }} 67 68 ics := mockedICS(sh.exec) 69 err := ics.Enable() 70 assert.EqualError(t, err, "failed to Enable RemoteAccess service: failed to get RemoteAccess service startup type: expected error") 71 } 72 73 func Test_errorSettingServiceStartTypeOnEnable(t *testing.T) { 74 sh := mockPowerShell{commands: map[string]mockShellResult{ 75 "Set-Service -Name RemoteAccess -StartupType automatic": {nil, errors.New("expected error")}, 76 }} 77 78 ics := mockedICS(sh.exec) 79 err := ics.Enable() 80 assert.EqualError(t, err, "failed to Enable RemoteAccess service: failed to set RemoteAccess service startup type to automatic: expected error") 81 } 82 83 func Test_errorStartingServiceOnEnable(t *testing.T) { 84 sh := mockPowerShell{commands: map[string]mockShellResult{ 85 "Start-Service -Name RemoteAccess": {nil, errors.New("expected error")}, 86 }} 87 88 ics := mockedICS(sh.exec) 89 err := ics.Enable() 90 assert.EqualError(t, err, "failed to Enable RemoteAccess service: failed to start RemoteAccess service: expected error") 91 } 92 93 func Test_errorGettingPublicInterfaceOnEnable(t *testing.T) { 94 sh := mockPowerShell{commands: map[string]mockShellResult{ 95 "Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {nil, errors.New("expected error")}, 96 }} 97 98 ics := mockedICS(sh.exec) 99 err := ics.Enable() 100 assert.EqualError(t, err, "failed to get public interface name: failed to get interface from the default route: expected error") 101 } 102 103 func Test_errorApplyingSharingConfigOnEnable(t *testing.T) { 104 ifaces, _ := net.Interfaces() 105 iface := ifaces[0] 106 107 sh := mockPowerShell{commands: map[string]mockShellResult{ 108 "Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {[]byte(strconv.Itoa(iface.Index)), nil}, 109 110 `regsvr32 /s hnetcfg.dll; 111 $netShare = New-Object -ComObject HNetCfg.HNetShare; 112 $c = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq "` + iface.Name + `" }; 113 $config = $netShare.INetSharingConfigurationForINetConnection.Invoke($c);$config.EnableSharing(0)`: {nil, errors.New("expected error")}, 114 }} 115 116 ics := mockedICS(sh.exec) 117 err := ics.Enable() 118 assert.EqualError(t, err, "failed to enable internet connection sharing: expected error") 119 } 120 121 func Test_Enable(t *testing.T) { 122 ifaces, _ := net.Interfaces() 123 iface := ifaces[0] 124 125 sh := mockPowerShell{commands: map[string]mockShellResult{ 126 "Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {[]byte(strconv.Itoa(iface.Index)), nil}, 127 }} 128 129 ics := mockedICS(sh.exec) 130 err := ics.Enable() 131 assert.NoError(t, err) 132 } 133 134 func Test_AddDel(t *testing.T) { 135 sh := mockPowerShell{commands: map[string]mockShellResult{ 136 `Get-WmiObject Win32_NetworkAdapter | Where-Object {$_.ServiceName -eq "tap0901"} | foreach { $_.NetConnectionID }`: {[]byte("myst0"), nil}, 137 }} 138 139 ics := mockedICS(sh.exec) 140 _, vpnNetwork, _ := net.ParseCIDR("127.0.0.1/24") 141 _, err := ics.Setup(Options{ 142 VPNNetwork: *vpnNetwork, 143 ProviderExtIP: net.ParseIP("8.8.8.8"), 144 }) 145 assert.NoError(t, err) 146 147 err = ics.Del(nil) 148 assert.NoError(t, err) 149 } 150 151 func Test_errorInterfaceOnAdd(t *testing.T) { 152 sh := mockPowerShell{commands: map[string]mockShellResult{}} 153 154 ics := mockedICS(sh.exec) 155 _, vpnNetwork, _ := net.ParseCIDR("8.8.8.8/24") 156 _, err := ics.Setup(Options{ 157 VPNNetwork: *vpnNetwork, 158 ProviderExtIP: net.ParseIP("8.8.8.8"), 159 }) 160 assert.EqualError(t, err, "failed to find suitable interface: interface not found") 161 } 162 163 func Test_errorRevertStartupTypeOnDisable(t *testing.T) { 164 ifaces, _ := net.Interfaces() 165 iface := ifaces[0] 166 167 sh := mockPowerShell{commands: map[string]mockShellResult{ 168 "Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {[]byte(strconv.Itoa(iface.Index)), nil}, 169 "Set-Service -Name RemoteAccess -StartupType testStatus": {nil, errors.New("expected error")}, 170 }} 171 172 ics := mockedICS(sh.exec) 173 ics.remoteAccessStatus = "testStatus" 174 err := ics.Disable() 175 176 assert.EqualError(t, err, "failed to revert RemoteAccess service startup type: expected error") 177 } 178 179 func Test_errorGettingPublicInterfaceOnDisable(t *testing.T) { 180 sh := mockPowerShell{commands: map[string]mockShellResult{ 181 "Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {nil, errors.New("expected error")}, 182 }} 183 184 ics := mockedICS(sh.exec) 185 err := ics.Disable() 186 187 assert.EqualError(t, err, "failed to get public interface name: failed to get interface from the default route: expected error") 188 } 189 190 func Test_Disable(t *testing.T) { 191 ifaces, _ := net.Interfaces() 192 iface := ifaces[0] 193 194 sh := mockPowerShell{commands: map[string]mockShellResult{ 195 "Get-WmiObject -Class Win32_IP4RouteTable | where { $_.destination -eq '0.0.0.0' -and $_.mask -eq '0.0.0.0'} | foreach { $_.InterfaceIndex }": {[]byte(strconv.Itoa(iface.Index)), nil}, 196 }} 197 198 ics := mockedICS(sh.exec) 199 err := ics.Disable() 200 201 assert.NoError(t, err) 202 } 203 204 type mockShellResult struct { 205 output []byte 206 err error 207 } 208 209 type mockPowerShell struct { 210 err error 211 commands map[string]mockShellResult 212 } 213 214 func (sh *mockPowerShell) exec(cmd string) ([]byte, error) { 215 if c, ok := sh.commands[cmd]; ok { 216 return c.output, c.err 217 } 218 return nil, sh.err 219 } 220 221 func mockICSConfig(_map map[string]string) (map[string]string, error) { 222 return nil, nil 223 }