From eec739b9dece1c6fc57010e7c9f879bc6e8a8f63 Mon Sep 17 00:00:00 2001 From: "Alex Ellis (OpenFaaS Ltd)" Date: Sun, 21 Feb 2021 18:51:39 +0000 Subject: [PATCH] Add test for isCNIResultForPID Signed-off-by: Alex Ellis (OpenFaaS Ltd) --- pkg/cninetwork/cni_network.go | 60 ++++++++++++++++++++-------- pkg/cninetwork/cni_network_test.go | 63 ++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 16 deletions(-) create mode 100644 pkg/cninetwork/cni_network_test.go diff --git a/pkg/cninetwork/cni_network.go b/pkg/cninetwork/cni_network.go index 3971b9f..e8e5686 100644 --- a/pkg/cninetwork/cni_network.go +++ b/pkg/cninetwork/cni_network.go @@ -147,33 +147,61 @@ func DeleteCNINetwork(ctx context.Context, cni gocni.CNI, client *containerd.Cli return errors.Wrapf(containerErr, "Unable to find container: %s, error: %s", name, containerErr) } -// GetIPAddress returns the IP address from container based on name and PID -func GetIPAddress(name string, PID uint32) (string, error) { - processName := fmt.Sprintf("%s-%d", name, PID) +// GetIPAddress returns the IP address from container based on container name and PID +func GetIPAddress(container string, PID uint32) (string, error) { CNIDir := path.Join(CNIDataDir, defaultNetworkName) files, err := ioutil.ReadDir(CNIDir) if err != nil { - return "", fmt.Errorf("failed to read CNI dir for container %s: %v", name, err) + return "", fmt.Errorf("failed to read CNI dir for container %s: %v", container, err) } for _, file := range files { - f, err := os.Open(filepath.Join(CNIDir, file.Name())) + // each fileName is an IP address + fileName := file.Name() + + resultsFile := filepath.Join(CNIDir, fileName) + found, err := isCNIResultForPID(resultsFile, container, PID) if err != nil { - return "", fmt.Errorf("failed to open CNI IP file for %s/%s: %v", CNIDir, file.Name(), err) + return "", err } - reader := bufio.NewReader(f) - text, _ := reader.ReadString('\n') - if strings.Contains(text, processName) { - i, _ := reader.ReadString('\n') - if strings.Contains(i, defaultIfPrefix) { - f.Close() - return file.Name(), nil - } + + if found { + return fileName, nil } - f.Close() } - return "", fmt.Errorf("unable to get IP address for container %s", name) + + return "", fmt.Errorf("unable to get IP address for container: %s", container) +} + +// isCNIResultForPID confirms if the CNI result file contains the +// process name, PID and interface name +// +// Example: +// +// /var/run/cni/openfaas-cni-bridge/10.62.0.2 +// +// nats-621 +// eth1 +func isCNIResultForPID(fileName, container string, PID uint32) (bool, error) { + found := false + + f, err := os.Open(fileName) + if err != nil { + return false, fmt.Errorf("failed to open CNI IP file for %s: %v", fileName, err) + } + defer f.Close() + + reader := bufio.NewReader(f) + processLine, _ := reader.ReadString('\n') + if strings.Contains(processLine, fmt.Sprintf("%s-%d", container, PID)) { + ethNameLine, _ := reader.ReadString('\n') + if strings.Contains(ethNameLine, defaultIfPrefix) { + found = true + } + } + + return found, nil } // CNIGateway returns the gateway for default subnet diff --git a/pkg/cninetwork/cni_network_test.go b/pkg/cninetwork/cni_network_test.go new file mode 100644 index 0000000..ef19d41 --- /dev/null +++ b/pkg/cninetwork/cni_network_test.go @@ -0,0 +1,63 @@ +package cninetwork + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func Test_isCNIResultForPID_Found(t *testing.T) { + body := `nats-621 +eth1` + fileName := `10.62.0.2` + container := "nats" + PID := uint32(621) + fullPath := filepath.Join(os.TempDir(), fileName) + + err := ioutil.WriteFile(fullPath, []byte(body), 0700) + if err != nil { + t.Fatalf(err.Error()) + } + defer func() { + os.Remove(fullPath) + }() + + got, err := isCNIResultForPID(fullPath, container, PID) + + if err != nil { + t.Fatalf(err.Error()) + } + + want := true + if got != want { + t.Fatalf("want %v, but got %v", want, got) + } +} + +func Test_isCNIResultForPID_NoMatch(t *testing.T) { + body := `nats-621 +eth1` + fileName := `10.62.0.3` + container := "gateway" + PID := uint32(621) + fullPath := filepath.Join(os.TempDir(), fileName) + + err := ioutil.WriteFile(fullPath, []byte(body), 0700) + if err != nil { + t.Fatalf(err.Error()) + } + defer func() { + os.Remove(fullPath) + }() + + got, err := isCNIResultForPID(fullPath, container, PID) + + if err != nil { + t.Fatalf(err.Error()) + } + want := false + if got != want { + t.Fatalf("want %v, but got %v", want, got) + } +}