package files import ( "io/fs" "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/ini.v1" ) func ptrTo[T any](value T) *T { return &value } func Test_Source_ParseWireguardConf(t *testing.T) { t.Parallel() t.Run("fail reading from file", func(t *testing.T) { t.Parallel() dirPath := t.TempDir() wireguard, err := ParseWireguardConf(dirPath) assert.Equal(t, WireguardConfig{}, wireguard) assert.Error(t, err) assert.Regexp(t, `loading ini from reader: BOM: read .+: is a directory`, err.Error()) }) t.Run("no file", func(t *testing.T) { t.Parallel() noFile := filepath.Join(t.TempDir(), "doesnotexist") wireguard, err := ParseWireguardConf(noFile) assert.Equal(t, WireguardConfig{}, wireguard) assert.NoError(t, err) }) testCases := map[string]struct { fileContent string wireguard WireguardConfig errMessage string }{ "ini load error": { fileContent: "invalid", errMessage: "loading ini from reader: key-value delimiter not found: invalid", }, "empty file": {}, "interface_section_missing": { fileContent: ` [Peer] PresharedKey = YJ680VN+dGrdsWNjSFqZ6vvwuiNhbq502ZL3G7Q3o3g= `, wireguard: WireguardConfig{ PreSharedKey: ptrTo("YJ680VN+dGrdsWNjSFqZ6vvwuiNhbq502ZL3G7Q3o3g="), }, }, "success": { fileContent: ` [Interface] PrivateKey = QOlCgyA/Sn/c/+YNTIEohrjm8IZV+OZ2AUFIoX20sk8= Address = 10.38.22.35/32 DNS = 193.138.218.74 [Peer] PresharedKey = YJ680VN+dGrdsWNjSFqZ6vvwuiNhbq502ZL3G7Q3o3g= `, wireguard: WireguardConfig{ PrivateKey: ptrTo("QOlCgyA/Sn/c/+YNTIEohrjm8IZV+OZ2AUFIoX20sk8="), PreSharedKey: ptrTo("YJ680VN+dGrdsWNjSFqZ6vvwuiNhbq502ZL3G7Q3o3g="), Addresses: ptrTo("10.38.22.35/32"), }, }, } for testName, testCase := range testCases { t.Run(testName, func(t *testing.T) { t.Parallel() configFile := filepath.Join(t.TempDir(), "wg.conf") const permission = fs.FileMode(0o600) err := os.WriteFile(configFile, []byte(testCase.fileContent), permission) require.NoError(t, err) wireguard, err := ParseWireguardConf(configFile) assert.Equal(t, testCase.wireguard, wireguard) if testCase.errMessage != "" { assert.EqualError(t, err, testCase.errMessage) } else { assert.NoError(t, err) } }) } } func Test_parseWireguardInterfaceSection(t *testing.T) { t.Parallel() testCases := map[string]struct { iniData string privateKey *string addresses *string }{ "no_fields": { iniData: `[Interface]`, }, "only_private_key": { iniData: `[Interface] PrivateKey = x `, privateKey: ptrTo("x"), }, "all_fields": { iniData: ` [Interface] PrivateKey = QOlCgyA/Sn/c/+YNTIEohrjm8IZV+OZ2AUFIoX20sk8= Address = 10.38.22.35/32 `, privateKey: ptrTo("QOlCgyA/Sn/c/+YNTIEohrjm8IZV+OZ2AUFIoX20sk8="), addresses: ptrTo("10.38.22.35/32"), }, } for testName, testCase := range testCases { t.Run(testName, func(t *testing.T) { t.Parallel() iniFile, err := ini.Load([]byte(testCase.iniData)) require.NoError(t, err) iniSection, err := iniFile.GetSection("Interface") require.NoError(t, err) privateKey, addresses := parseWireguardInterfaceSection(iniSection) assert.Equal(t, testCase.privateKey, privateKey) assert.Equal(t, testCase.addresses, addresses) }) } } func Test_parseWireguardPeerSection(t *testing.T) { t.Parallel() testCases := map[string]struct { iniData string preSharedKey *string publicKey *string endpointIP *string endpointPort *string errMessage string }{ "public key set": { iniData: `[Peer] PublicKey = QOlCgyA/Sn/c/+YNTIEohrjm8IZV+OZ2AUFIoX20sk8=`, publicKey: ptrTo("QOlCgyA/Sn/c/+YNTIEohrjm8IZV+OZ2AUFIoX20sk8="), }, "endpoint_only_host": { iniData: `[Peer] Endpoint = x`, endpointIP: ptrTo("x"), }, "endpoint_no_port": { iniData: `[Peer] Endpoint = x:`, endpointIP: ptrTo("x"), endpointPort: ptrTo(""), }, "valid_endpoint": { iniData: `[Peer] Endpoint = 1.2.3.4:51820`, endpointIP: ptrTo("1.2.3.4"), endpointPort: ptrTo("51820"), }, "all_set": { iniData: `[Peer] PublicKey = QOlCgyA/Sn/c/+YNTIEohrjm8IZV+OZ2AUFIoX20sk8= Endpoint = 1.2.3.4:51820`, publicKey: ptrTo("QOlCgyA/Sn/c/+YNTIEohrjm8IZV+OZ2AUFIoX20sk8="), endpointIP: ptrTo("1.2.3.4"), endpointPort: ptrTo("51820"), }, } for testName, testCase := range testCases { t.Run(testName, func(t *testing.T) { t.Parallel() iniFile, err := ini.Load([]byte(testCase.iniData)) require.NoError(t, err) iniSection, err := iniFile.GetSection("Peer") require.NoError(t, err) preSharedKey, publicKey, endpointIP, endpointPort := parseWireguardPeerSection(iniSection) assert.Equal(t, testCase.preSharedKey, preSharedKey) assert.Equal(t, testCase.publicKey, publicKey) assert.Equal(t, testCase.endpointIP, endpointIP) assert.Equal(t, testCase.endpointPort, endpointPort) if testCase.errMessage != "" { assert.EqualError(t, err, testCase.errMessage) } else { assert.NoError(t, err) } }) } }