chore(updater): common GetServers signature
- Log warnings when running outside of CLI mode - Remove updater CLI bool setting - Warnings are logged in updating functions
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
package ipvanish
|
||||
|
||||
//go:generate mockgen -destination=mocks_test.go -package $GOPACKAGE . Warner
|
||||
46
internal/provider/ipvanish/updater/mocks_test.go
Normal file
46
internal/provider/ipvanish/updater/mocks_test.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/qdm12/gluetun/internal/provider/ipvanish/updater (interfaces: Warner)
|
||||
|
||||
// Package ipvanish is a generated GoMock package.
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
// MockWarner is a mock of Warner interface.
|
||||
type MockWarner struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockWarnerMockRecorder
|
||||
}
|
||||
|
||||
// MockWarnerMockRecorder is the mock recorder for MockWarner.
|
||||
type MockWarnerMockRecorder struct {
|
||||
mock *MockWarner
|
||||
}
|
||||
|
||||
// NewMockWarner creates a new mock instance.
|
||||
func NewMockWarner(ctrl *gomock.Controller) *MockWarner {
|
||||
mock := &MockWarner{ctrl: ctrl}
|
||||
mock.recorder = &MockWarnerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockWarner) EXPECT() *MockWarnerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Warn mocks base method.
|
||||
func (m *MockWarner) Warn(arg0 string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Warn", arg0)
|
||||
}
|
||||
|
||||
// Warn indicates an expected call of Warn.
|
||||
func (mr *MockWarnerMockRecorder) Warn(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Warn", reflect.TypeOf((*MockWarner)(nil).Warn), arg0)
|
||||
}
|
||||
@@ -10,23 +10,20 @@ import (
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/updater/openvpn"
|
||||
"github.com/qdm12/gluetun/internal/updater/resolver"
|
||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
var ErrNotEnoughServers = errors.New("not enough servers found")
|
||||
|
||||
func GetServers(ctx context.Context, unzipper unzip.Unzipper,
|
||||
presolver resolver.Parallel, minServers int) (
|
||||
servers []models.Server, warnings []string, err error) {
|
||||
func (u *Updater) GetServers(ctx context.Context, minServers int) (
|
||||
servers []models.Server, err error) {
|
||||
const url = "https://www.ipvanish.com/software/configs/configs.zip"
|
||||
contents, err := unzipper.FetchAndExtract(ctx, url)
|
||||
contents, err := u.unzipper.FetchAndExtract(ctx, url)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, err
|
||||
} else if len(contents) < minServers {
|
||||
return nil, nil, fmt.Errorf("%w: %d and expected at least %d",
|
||||
return nil, fmt.Errorf("%w: %d and expected at least %d",
|
||||
ErrNotEnoughServers, len(contents), minServers)
|
||||
}
|
||||
|
||||
@@ -41,27 +38,24 @@ func GetServers(ctx context.Context, unzipper unzip.Unzipper,
|
||||
tcp, udp, err := openvpn.ExtractProto(content)
|
||||
if err != nil {
|
||||
// treat error as warning and go to next file
|
||||
warning := err.Error() + ": in " + fileName
|
||||
warnings = append(warnings, warning)
|
||||
u.warner.Warn(err.Error() + " in " + fileName)
|
||||
continue
|
||||
}
|
||||
|
||||
hostname, warning, err := openvpn.ExtractHost(content)
|
||||
if warning != "" {
|
||||
warnings = append(warnings, warning)
|
||||
u.warner.Warn(warning)
|
||||
}
|
||||
if err != nil {
|
||||
// treat error as warning and go to next file
|
||||
warning := err.Error() + " in " + fileName
|
||||
warnings = append(warnings, warning)
|
||||
u.warner.Warn(err.Error() + " in " + fileName)
|
||||
continue
|
||||
}
|
||||
|
||||
country, city, err := parseFilename(fileName, hostname, titleCaser)
|
||||
if err != nil {
|
||||
// treat error as warning and go to next file
|
||||
warning := err.Error() + " in " + fileName
|
||||
warnings = append(warnings, warning)
|
||||
u.warner.Warn(err.Error() + " in " + fileName)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -69,15 +63,17 @@ func GetServers(ctx context.Context, unzipper unzip.Unzipper,
|
||||
}
|
||||
|
||||
if len(hts) < minServers {
|
||||
return nil, warnings, fmt.Errorf("%w: %d and expected at least %d",
|
||||
return nil, fmt.Errorf("%w: %d and expected at least %d",
|
||||
ErrNotEnoughServers, len(hts), minServers)
|
||||
}
|
||||
|
||||
hosts := hts.toHostsSlice()
|
||||
hostToIPs, newWarnings, err := resolveHosts(ctx, presolver, hosts, minServers)
|
||||
warnings = append(warnings, newWarnings...)
|
||||
hostToIPs, warnings, err := resolveHosts(ctx, u.presolver, hosts, minServers)
|
||||
for _, warning := range warnings {
|
||||
u.warner.Warn(warning)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, warnings, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hts.adaptWithIPs(hostToIPs)
|
||||
@@ -85,11 +81,11 @@ func GetServers(ctx context.Context, unzipper unzip.Unzipper,
|
||||
servers = hts.toServersSlice()
|
||||
|
||||
if len(servers) < minServers {
|
||||
return nil, warnings, fmt.Errorf("%w: %d and expected at least %d",
|
||||
return nil, fmt.Errorf("%w: %d and expected at least %d",
|
||||
ErrNotEnoughServers, len(servers), minServers)
|
||||
}
|
||||
|
||||
sortServers(servers)
|
||||
|
||||
return servers, warnings, nil
|
||||
return servers, nil
|
||||
}
|
||||
|
||||
@@ -16,12 +16,15 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_GetServers(t *testing.T) {
|
||||
func Test_Updater_GetServers(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
// Inputs
|
||||
minServers int
|
||||
|
||||
// Mocks
|
||||
warnerBuilder func(ctrl *gomock.Controller) Warner
|
||||
|
||||
// Unzip
|
||||
unzipContents map[string][]byte
|
||||
unzipErr error
|
||||
@@ -35,48 +38,67 @@ func Test_GetServers(t *testing.T) {
|
||||
resolveErr error
|
||||
|
||||
// Output
|
||||
servers []models.Server
|
||||
warnings []string
|
||||
err error
|
||||
servers []models.Server
|
||||
err error
|
||||
}{
|
||||
"unzipper error": {
|
||||
unzipErr: errors.New("dummy"),
|
||||
err: errors.New("dummy"),
|
||||
warnerBuilder: func(ctrl *gomock.Controller) Warner { return nil },
|
||||
unzipErr: errors.New("dummy"),
|
||||
err: errors.New("dummy"),
|
||||
},
|
||||
"not enough unzip contents": {
|
||||
minServers: 1,
|
||||
warnerBuilder: func(ctrl *gomock.Controller) Warner { return nil },
|
||||
unzipContents: map[string][]byte{},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"no openvpn file": {
|
||||
minServers: 1,
|
||||
warnerBuilder: func(ctrl *gomock.Controller) Warner { return nil },
|
||||
unzipContents: map[string][]byte{"somefile.txt": {}},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"invalid proto": {
|
||||
minServers: 1,
|
||||
minServers: 1,
|
||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
||||
warner := NewMockWarner(ctrl)
|
||||
warner.EXPECT().Warn("unknown protocol: invalid in badproto.ovpn")
|
||||
return warner
|
||||
},
|
||||
unzipContents: map[string][]byte{"badproto.ovpn": []byte(`proto invalid`)},
|
||||
warnings: []string{"unknown protocol: invalid: in badproto.ovpn"},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"no host": {
|
||||
minServers: 1,
|
||||
minServers: 1,
|
||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
||||
warner := NewMockWarner(ctrl)
|
||||
warner.EXPECT().Warn("remote host not found in nohost.ovpn")
|
||||
return warner
|
||||
},
|
||||
unzipContents: map[string][]byte{"nohost.ovpn": []byte(``)},
|
||||
warnings: []string{"remote host not found in nohost.ovpn"},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"multiple hosts": {
|
||||
minServers: 1,
|
||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
||||
warner := NewMockWarner(ctrl)
|
||||
warner.EXPECT().Warn("only using the first host \"hosta\" and discarding 1 other hosts")
|
||||
return warner
|
||||
},
|
||||
unzipContents: map[string][]byte{
|
||||
"ipvanish-CA-City-A-hosta.ovpn": []byte("remote hosta\nremote hostb"),
|
||||
},
|
||||
expectResolve: true,
|
||||
hostsToResolve: []string{"hosta"},
|
||||
resolveSettings: getResolveSettings(1),
|
||||
warnings: []string{"only using the first host \"hosta\" and discarding 1 other hosts"},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"resolve error": {
|
||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
||||
warner := NewMockWarner(ctrl)
|
||||
warner.EXPECT().Warn("resolve warning")
|
||||
return warner
|
||||
},
|
||||
unzipContents: map[string][]byte{
|
||||
"ipvanish-CA-City-A-hosta.ovpn": []byte("remote hosta"),
|
||||
},
|
||||
@@ -85,19 +107,27 @@ func Test_GetServers(t *testing.T) {
|
||||
resolveSettings: getResolveSettings(0),
|
||||
resolveWarnings: []string{"resolve warning"},
|
||||
resolveErr: errors.New("dummy"),
|
||||
warnings: []string{"resolve warning"},
|
||||
err: errors.New("dummy"),
|
||||
},
|
||||
"filename parsing error": {
|
||||
minServers: 1,
|
||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
||||
warner := NewMockWarner(ctrl)
|
||||
warner.EXPECT().Warn("country code is unknown: unknown in ipvanish-unknown-City-A-hosta.ovpn")
|
||||
return warner
|
||||
},
|
||||
unzipContents: map[string][]byte{
|
||||
"ipvanish-unknown-City-A-hosta.ovpn": []byte("remote hosta"),
|
||||
},
|
||||
warnings: []string{"country code is unknown: unknown in ipvanish-unknown-City-A-hosta.ovpn"},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"success": {
|
||||
minServers: 1,
|
||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
||||
warner := NewMockWarner(ctrl)
|
||||
warner.EXPECT().Warn("resolve warning")
|
||||
return warner
|
||||
},
|
||||
unzipContents: map[string][]byte{
|
||||
"ipvanish-CA-City-A-hosta.ovpn": []byte("remote hosta"),
|
||||
"ipvanish-LU-City-B-hostb.ovpn": []byte("remote hostb"),
|
||||
@@ -128,7 +158,6 @@ func Test_GetServers(t *testing.T) {
|
||||
IPs: []net.IP{{3, 3, 3, 3}, {4, 4, 4, 4}},
|
||||
},
|
||||
},
|
||||
warnings: []string{"resolve warning"},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
@@ -150,10 +179,13 @@ func Test_GetServers(t *testing.T) {
|
||||
Return(testCase.hostToIPs, testCase.resolveWarnings, testCase.resolveErr)
|
||||
}
|
||||
|
||||
servers, warnings, err := GetServers(ctx, unzipper, presolver, testCase.minServers)
|
||||
warner := testCase.warnerBuilder(ctrl)
|
||||
|
||||
updater := New(unzipper, presolver, warner)
|
||||
|
||||
servers, err := updater.GetServers(ctx, testCase.minServers)
|
||||
|
||||
assert.Equal(t, testCase.servers, servers)
|
||||
assert.Equal(t, testCase.warnings, warnings)
|
||||
if testCase.err != nil {
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, testCase.err.Error(), err.Error())
|
||||
|
||||
25
internal/provider/ipvanish/updater/updater.go
Normal file
25
internal/provider/ipvanish/updater/updater.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"github.com/qdm12/gluetun/internal/updater/resolver"
|
||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
||||
)
|
||||
|
||||
type Updater struct {
|
||||
unzipper unzip.Unzipper
|
||||
presolver resolver.Parallel
|
||||
warner Warner
|
||||
}
|
||||
|
||||
type Warner interface {
|
||||
Warn(s string)
|
||||
}
|
||||
|
||||
func New(unzipper unzip.Unzipper, presolver resolver.Parallel,
|
||||
warner Warner) *Updater {
|
||||
return &Updater{
|
||||
unzipper: unzipper,
|
||||
presolver: presolver,
|
||||
warner: warner,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user