Skip to content

Commit

Permalink
Update tests in internal/vpncscript
Browse files Browse the repository at this point in the history
Signed-off-by: hwipl <33433250+hwipl@users.noreply.github.com>
  • Loading branch information
hwipl committed Feb 13, 2024
1 parent 3884b86 commit 080e173
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 43 deletions.
12 changes: 7 additions & 5 deletions internal/vpncscript/client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package vpncscript

import (
"fmt"
"net"

log "github.com/sirupsen/logrus"
Expand All @@ -9,11 +10,11 @@ import (
)

// runClient interacts with the daemon over the api
func runClient(socketFile string, configUpdate *daemon.VPNConfigUpdate) {
func runClient(socketFile string, configUpdate *daemon.VPNConfigUpdate) error {
// connect to daemon
conn, err := net.Dial("unix", socketFile)
if err != nil {
log.WithError(err).Fatal("VPNCScript could not connect to Daemon")
return fmt.Errorf("VPNCScript could not connect to Daemon: %w", err)
}
defer func() {
_ = conn.Close()
Expand All @@ -22,18 +23,18 @@ func runClient(socketFile string, configUpdate *daemon.VPNConfigUpdate) {
// send message to daemon
b, err := configUpdate.JSON()
if err != nil {
log.WithError(err).Fatal("VPNCScript could not convert config update to JSON")
return fmt.Errorf("VPNCScript could not convert config update to JSON: %w", err)
}
msg := api.NewMessage(api.TypeVPNConfigUpdate, b)
err = api.WriteMessage(conn, msg)
if err != nil {
log.WithError(err).Fatal("VPNCScript could not send message to Daemon")
return fmt.Errorf("VPNCScript could not send message to Daemon: %w", err)
}

// receive reply
reply, err := api.ReadMessage(conn)
if err != nil {
log.WithError(err).Fatal("VPNCScript could not receive reply from Daemon")
return fmt.Errorf("VPNCScript could not receive reply from Daemon: %w", err)
}
switch reply.Type {
case api.TypeOK:
Expand All @@ -43,4 +44,5 @@ func runClient(socketFile string, configUpdate *daemon.VPNConfigUpdate) {
log.WithField("error", string(reply.Value)).
Error("VPNCScript received error reply from Daemon")
}
return nil
}
43 changes: 43 additions & 0 deletions internal/vpncscript/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package vpncscript

import (
"path/filepath"
"testing"

"github.com/telekom-mms/oc-daemon/internal/api"
"github.com/telekom-mms/oc-daemon/internal/daemon"
)

// TestRunClient tests runClient.
func TestRunClient(t *testing.T) {
sockfile := filepath.Join(t.TempDir(), "sockfile")
config := api.NewConfig()
config.SocketFile = sockfile

// without errors
server := api.NewServer(config)
go func() {
for r := range server.Requests() {
r.Close()
}
}()
server.Start()
if err := runClient(sockfile, &daemon.VPNConfigUpdate{}); err != nil {
t.Fatal(err)
}
server.Stop()

// with error reply
server = api.NewServer(config)
go func() {
for r := range server.Requests() {
r.Error("test error")
r.Close()
}
}()
server.Start()
if err := runClient(sockfile, &daemon.VPNConfigUpdate{}); err != nil {
t.Fatal(err)
}
server.Stop()
}
36 changes: 25 additions & 11 deletions internal/vpncscript/cmd.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package vpncscript

import (
"errors"
"flag"
"fmt"
"os"
Expand All @@ -14,17 +15,20 @@ const (
socketFile = runDir + "/daemon.sock"
)

// Run is the main entry point of vpnc script
func Run() {
func run(args []string) error {
// parse command line
verbose := flag.Bool("verbose", false, "enable verbose output")
version := flag.Bool("version", false, "print version")
flag.Parse()
flags := flag.NewFlagSet(args[0], flag.ContinueOnError)
verbose := flags.Bool("verbose", false, "enable verbose output")
version := flags.Bool("version", false, "print version")

if err := flags.Parse(args[1:]); err != nil {
return err
}

// print version?
if *version {
fmt.Println(daemon.Version)
os.Exit(0)
return nil
}

// parse environment variables
Expand All @@ -47,16 +51,26 @@ func Run() {
// handle reason environment variable
switch e.reason {
case "pre-init":
return
return nil
case "connect", "disconnect":
c := createConfigUpdate(e)
log.WithField("update", c).Debug("VPNCScript created config update")
runClient(socketFile, c)
return runClient(socketFile, c)
case "attempt-reconnect":
return
return nil
case "reconnect":
return
return nil
default:
log.Fatal("VPNCScript called with unknown reason")
return errors.New("VPNCScript called with unknown reason")
}
}

// Run is the main entry point of vpnc script
func Run() {
if err := run(os.Args); err != nil {
if err != flag.ErrHelp {
log.Fatal(err)
}
return
}
}
64 changes: 64 additions & 0 deletions internal/vpncscript/cmd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package vpncscript

import (
"flag"
"os"
"path/filepath"
"testing"
)

// TestRun tests run.
func TestRun(t *testing.T) {
// test invalid arg
if err := run([]string{"test", "-invalid"}); err == nil || err == flag.ErrHelp {
t.Errorf("invalid argument should return error, got: %v", err)
}

// test with "-version"
if err := run([]string{"test", "-version"}); err != nil {
t.Errorf("version should not return error, got: %v", err)
}

// test with "-help"
if err := run([]string{"test", "-help"}); err != flag.ErrHelp {
t.Errorf("help should return ErrHelp, got: %v", err)
}

// prepare environment with not existing sockfile
os.Clearenv()
sockfile := filepath.Join(t.TempDir(), "sockfile")
if err := os.Setenv("oc_daemon_socket_file", sockfile); err != nil {
t.Fatal(err)
}
if err := os.Setenv("oc_daemon_verbose", "true"); err != nil {
t.Fatal(err)
}

// test with errors
for _, v := range []string{
"connect",
"disconnect",
"invalid",
} {
if err := os.Setenv("reason", v); err != nil {
t.Fatal(err)
}
if err := run([]string{"test"}); err == nil {
t.Errorf("%s: should return error", v)
}
}

// test without errors
for _, v := range []string{
"pre-init",
"attempt-reconnect",
"reconnect",
} {
if err := os.Setenv("reason", v); err != nil {
t.Fatal(err)
}
if err := run([]string{"test"}); err != nil {
t.Errorf("%s: should not return error, got: %v", v, err)
}
}
}
23 changes: 8 additions & 15 deletions internal/vpncscript/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,15 @@ func createConfigIPv4(env *env, config *vpnconfig.Config) {
func createConfigIPv6(env *env, config *vpnconfig.Config) {
// set ip and netmask
// internalIP6Netmask should contain IP in CIDR representation
if env.internalIP6Netmask == "" {
// no ipv6 configuration
return
}
ip, ipnet, err := net.ParseCIDR(env.internalIP6Netmask)
if err != nil {
log.WithError(err).
Fatal("VPNCScript could not parse IPv6 netmask")
if env.internalIP6Netmask != "" {
ip, ipnet, err := net.ParseCIDR(env.internalIP6Netmask)
if err != nil {
log.WithError(err).
Fatal("VPNCScript could not parse IPv6 netmask")
}
config.IPv6.Address = ip
config.IPv6.Netmask = ipnet.Mask
}
config.IPv6.Address = ip
config.IPv6.Netmask = ipnet.Mask
}

// createConfigDNS creates the DNS configuration in config from env
Expand Down Expand Up @@ -159,11 +157,6 @@ func createConfigFlags(env *env, config *vpnconfig.Config) {
func createConfig(env *env) *vpnconfig.Config {
config := vpnconfig.New()

// only use settings in env in connect case
if env.reason != "connect" {
return config
}

// set general configuration
createConfigGeneral(env, config)

Expand Down
10 changes: 9 additions & 1 deletion internal/vpncscript/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestCreateConfigSplit(t *testing.T) {
ciscoSplitInc: []string{},
ciscoSplitExc: []string{"172.16.0.0/16"},
ciscoIPv6SplitInc: []string{},
ciscoIPv6SplitExc: []string{},
ciscoIPv6SplitExc: []string{"2001:2:3:4::/64"},
dnsSplitExc: []string{"some.example.com", "other.example.com", "www.example.com"},
bypassVirtualSubnetsOnlyV4: true,
}
Expand Down Expand Up @@ -68,6 +68,9 @@ func TestCreateConfigUpdate(t *testing.T) {
internalIP4NetAddr: "192.168.1.0",
internalIP4DNS: "192.168.1.1",
internalIP4NBNS: "192.168.1.1",
internalIP6Address: "2001:3:2:1::1",
internalIP6Netmask: "2001:3:2:1::1/64",
internalIP6DNS: "2001:53:53:53::53",
ciscoDefDomain: "example.com",
ciscoBanner: "some banner",
ciscoSplitInc: []string{}, // splits are tested in TestCreateConfigSplit
Expand Down Expand Up @@ -95,9 +98,14 @@ func TestCreateConfigUpdate(t *testing.T) {
Address: net.IPv4(192, 168, 1, 123),
Netmask: net.IPv4Mask(255, 255, 255, 0),
},
IPv6: vpnconfig.Address{
Address: net.ParseIP("2001:3:2:1::1"),
Netmask: net.CIDRMask(64, 128),
},
DNS: vpnconfig.DNS{
DefaultDomain: "example.com",
ServersIPv4: []net.IP{net.IPv4(192, 168, 1, 1)},
ServersIPv6: []net.IP{net.ParseIP("2001:53:53:53::53")},
},
Split: vpnconfig.Split{
ExcludeDNS: []string{"some.example.com", "other.example.com", "www.example.com"},
Expand Down
53 changes: 42 additions & 11 deletions internal/vpncscript/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,47 @@ func TestParseEnvironmentSplit(t *testing.T) {
}
}

// test with invalid number in variable
if err := os.Setenv("CISCO_SPLIT_EXC", "invalid"); err != nil {
t.Fatal(err)
}
want := []string{}
got := parseEnvironmentSplit("CISCO_SPLIT_EXC")
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, want %v", got, want)
}

// test with not matching numbers
if err := os.Setenv("CISCO_SPLIT_EXC", "1"); err != nil {
t.Fatal(err)
}
want = []string{}
got = parseEnvironmentSplit("CISCO_SPLIT_EXC")
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, want %v", got, want)
}

// test with environment variables set
os.Setenv("CISCO_SPLIT_EXC", "3")
os.Setenv("CISCO_SPLIT_EXC_0_ADDR", "192.168.1.0")
os.Setenv("CISCO_SPLIT_EXC_0_MASKLEN", "24")
os.Setenv("CISCO_SPLIT_EXC_1_ADDR", "172.16.0.0")
os.Setenv("CISCO_SPLIT_EXC_1_MASKLEN", "16")
os.Setenv("CISCO_SPLIT_EXC_2_ADDR", "10.0.0.0")
os.Setenv("CISCO_SPLIT_EXC_2_MASKLEN", "8")

want := []string{
for k, v := range map[string]string{
"CISCO_SPLIT_EXC": "3",
"CISCO_SPLIT_EXC_0_ADDR": "192.168.1.0",
"CISCO_SPLIT_EXC_0_MASKLEN": "24",
"CISCO_SPLIT_EXC_1_ADDR": "172.16.0.0",
"CISCO_SPLIT_EXC_1_MASKLEN": "16",
"CISCO_SPLIT_EXC_2_ADDR": "10.0.0.0",
"CISCO_SPLIT_EXC_2_MASKLEN": "8",
} {
if err := os.Setenv(k, v); err != nil {
t.Fatal(err)
}
}

want = []string{
"192.168.1.0/24",
"172.16.0.0/16",
"10.0.0.0/8",
}
got := parseEnvironmentSplit("CISCO_SPLIT_EXC")
got = parseEnvironmentSplit("CISCO_SPLIT_EXC")
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, want %v", got, want)
}
Expand Down Expand Up @@ -346,9 +372,14 @@ X-CSTP-Disable-Always-On-VPN=true`,
"oc_daemon_socket_file": "/run/oc-daemon/test.socket",
"oc_daemon_verbose": "true",
} {
os.Setenv(k, v)
if err := os.Setenv(k, v); err != nil {
t.Fatal(err)
}
}

// print env
printDebugEnvironment()

// create expected env struct based on test environment
want := &env{
reason: "connect",
Expand Down

0 comments on commit 080e173

Please sign in to comment.