Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table-driven testing #167

Merged
merged 1 commit into from
Feb 16, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
275 changes: 158 additions & 117 deletions cmd/nettop/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"bufio"
"errors"
"fmt"
"os"
"path/filepath"
Expand All @@ -12,138 +11,177 @@ import (
"github.com/stretchr/testify/require"
)

func TestConnectionsOutput(t *testing.T) {
testsDir := getTestsDir()
dirPath := filepath.Join(testsDir, "onlineboutique", "kubernetes-manifests.yaml")
outFile := filepath.Join(testsDir, "onlineboutique", "output.json")
expectedOutput := filepath.Join(testsDir, "onlineboutique", "expected_output.json")
args := getTestArgs(dirPath, outFile, JSONFormat, false, false, false)

err := detectTopology(args)
require.Nil(t, err)

res, err := compareFiles(expectedOutput, outFile)
require.Nil(t, err)
require.True(t, res)

os.Remove(outFile)
type TestDetails struct {
name string
dirPath [][]string
outputFormat string
synthNetpols bool
quiet bool
verbose bool
expectError bool
expectedOutput []string
}

func TestConnectionsYamlOutput(t *testing.T) {
testsDir := getTestsDir()
dirPath := filepath.Join(testsDir, "onlineboutique", "kubernetes-manifests.yaml")
outFile := filepath.Join(testsDir, "onlineboutique", "output.yaml")
expectedOutput := filepath.Join(testsDir, "onlineboutique", "expected_output.yaml")
args := getTestArgs(dirPath, outFile, YamlFormat, false, false, false)

err := detectTopology(args)
require.Nil(t, err)

res, err := compareFiles(expectedOutput, outFile)
require.Nil(t, err)
require.True(t, res)

os.Remove(outFile)
}
var (
testCaseScenarios = []TestDetails{
{
"ConnectionsOutputJSON",
[][]string{{"onlineboutique", "kubernetes-manifests.yaml"}},
JSONFormat,
false,
false,
false,
false,
[]string{"onlineboutique", "expected_output.json"},
},
{
"ConnectionsOutputYAML",
[][]string{{"onlineboutique", "kubernetes-manifests.yaml"}},
YamlFormat,
false,
false,
false,
false,
[]string{"onlineboutique", "expected_output.yaml"},
},
{
"DirScan",
[][]string{{"onlineboutique"}},
JSONFormat,
false,
true,
false,
false,
[]string{"onlineboutique", "expected_dirscan_output.json"},
},
{
"NetpolsOnlineBoutiqueYAML",
[][]string{{"onlineboutique", "kubernetes-manifests.yaml"}},
YamlFormat,
true,
false,
false,
false,
[]string{"onlineboutique", "expected_netpol_output.yaml"},
},
{
"NetpolsMultiplePaths",
[][]string{{"k8s_wordpress_example", "mysql-deployment.yaml"}, {"k8s_wordpress_example", "wordpress-deployment.yaml"}},
JSONFormat,
true,
false,
false,
false,
[]string{"k8s_wordpress_example", "expected_netpol_output.json"},
},
{
"NetpolsOnlineBoutiqueJson",
[][]string{{"onlineboutique", "kubernetes-manifests.yaml"}},
JSONFormat,
true,
false,
false,
false,
[]string{"onlineboutique", "expected_netpol_output.json"},
},
{
"NetpolsSockshop",
[][]string{{"sockshop", "manifests"}},
JSONFormat,
true,
false,
true,
false,
[]string{"sockshop", "expected_netpol_output.json"},
},
{
"NetpolsK8sWordpress",
[][]string{{"k8s_wordpress_example"}},
JSONFormat,
true,
false,
true,
false,
[]string{"k8s_wordpress_example", "expected_netpol_output.json"},
},
{
"NetpolsK8sGuestbook",
[][]string{{"k8s_guestbook"}},
JSONFormat,
true,
false,
true,
false,
[]string{"k8s_guestbook", "expected_netpol_output.json"},
},
{
"NetpolsBookInfo",
[][]string{{"bookinfo"}},
JSONFormat,
true,
false,
true,
false,
[]string{"bookinfo", "expected_netpol_output.json"},
},
}

func TestDirScan(t *testing.T) {
testsDir := getTestsDir()
dirPath := filepath.Join(testsDir, "onlineboutique")
outFile := filepath.Join(dirPath, "output.json")
expectedOutput := filepath.Join(dirPath, "expected_dirscan_output.json")
args := getTestArgs(dirPath, outFile, JSONFormat, false, true, false)
currentDir, _ = os.Getwd()
testsDir = filepath.Join(currentDir, "..", "..", "tests")
)

err := detectTopology(args)
func (td *TestDetails) runTest(t *testing.T) {
t.Logf("Running test %s", td.name)
outFileName, err := getTempOutputFile()
require.Nil(t, err)

res, err := compareFiles(expectedOutput, outFile)
require.Nil(t, err)
require.True(t, res)
args := getTestArgs(td.dirPath, outFileName, td.outputFormat, td.synthNetpols, td.quiet, td.verbose)
err = detectTopology(args)

os.Remove(outFile)
}
if td.expectError {
require.NotNil(t, err)
} else {
require.Nil(t, err)
if td.expectedOutput != nil {
res, err := compareFiles(pathInTestsDir(td.expectedOutput), outFileName)
require.Nil(t, err)
require.True(t, res)

type TestDetails struct {
dirPath string
outFile string
expectedOutput string
}

func TestNetpolsJsonOutput(t *testing.T) {
testsDir := getTestsDir()
tests := map[string]TestDetails{} // map from test name to test details
tests["onlineboutique"] = TestDetails{dirPath: filepath.Join(testsDir, "onlineboutique", "kubernetes-manifests.yaml"),
outFile: filepath.Join(testsDir, "onlineboutique", "output.json"),
expectedOutput: filepath.Join(testsDir, "onlineboutique", "expected_netpol_output.json")}
tests["sockshop"] = TestDetails{dirPath: filepath.Join(testsDir, "sockshop", "manifests"),
outFile: filepath.Join(testsDir, "sockshop", "output.json"),
expectedOutput: filepath.Join(testsDir, "sockshop", "expected_netpol_output.json")}
tests["wordpress"] = TestDetails{dirPath: filepath.Join(testsDir, "k8s_wordpress_example"),
outFile: filepath.Join(testsDir, "k8s_wordpress_example", "output.json"),
expectedOutput: filepath.Join(testsDir, "k8s_wordpress_example", "expected_netpol_output.json")}
tests["guestbook"] = TestDetails{dirPath: filepath.Join(testsDir, "k8s_guestbook"),
outFile: filepath.Join(testsDir, "k8s_guestbook", "output.json"),
expectedOutput: filepath.Join(testsDir, "k8s_guestbook", "expected_netpol_output.json")}
tests["bookinfo"] = TestDetails{dirPath: filepath.Join(testsDir, "bookinfo"),
outFile: filepath.Join(testsDir, "bookinfo", "output.json"),
expectedOutput: filepath.Join(testsDir, "bookinfo", "expected_netpol_output.json")}

for testName, testDetails := range tests {
args := getTestArgs(testDetails.dirPath, testDetails.outFile, JSONFormat, true, false, true)
err := detectTopology(args)
require.Nilf(t, err, "on test %s", testName)

res, err := compareFiles(testDetails.expectedOutput, testDetails.outFile)
require.Nilf(t, err, "on test %s", testName)
require.Truef(t, res, "on test %s", testName)
os.Remove(testDetails.outFile)
os.Remove(outFileName)
}
}
}

func TestNetpolsYamlOutput(t *testing.T) {
testsDir := getTestsDir()
dirPath := filepath.Join(testsDir, "onlineboutique", "kubernetes-manifests.yaml")
outFile := filepath.Join(testsDir, "onlineboutique", "output.yaml")
expectedOutput := filepath.Join(testsDir, "onlineboutique", "expected_netpol_output.yaml")
args := getTestArgs(dirPath, outFile, YamlFormat, true, false, false)

err := detectTopology(args)
require.Nil(t, err)

res, err := compareFiles(expectedOutput, outFile)
require.Nil(t, err)
require.True(t, res)

os.Remove(outFile)
func TestAll(t *testing.T) {
for testIdx := range testCaseScenarios {
tc := &testCaseScenarios[testIdx] // rebind tc into this lexical scope to support reentrancy
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
tc.runTest(t)
})
}
}

func TestNetpolsMultiplePaths(t *testing.T) {
testsDir := getTestsDir()
dirPath1 := filepath.Join(testsDir, "k8s_wordpress_example", "mysql-deployment.yaml")
dirPath2 := filepath.Join(testsDir, "k8s_wordpress_example", "wordpress-deployment.yaml")
outFile := filepath.Join(testsDir, "k8s_wordpress_example", "netpols.yaml")
expectedOutput := filepath.Join(testsDir, "k8s_wordpress_example", "expected_netpol_output.json")
args := getTestArgs(dirPath1, outFile, JSONFormat, true, false, false)
args.DirPaths = append(args.DirPaths, dirPath2)

err := detectTopology(args)
require.Nil(t, err)

res, err := compareFiles(expectedOutput, outFile)
require.Nil(t, err)
require.True(t, res)

os.Remove(outFile)
func getTempOutputFile() (string, error) {
outFile, err := os.CreateTemp(os.TempDir(), "cta_temp")
if err != nil {
return "", err
}
outFileName := outFile.Name()
err = outFile.Close()
return outFileName, err
}

func getTestsDir() string {
currentDir, _ := os.Getwd()
return filepath.Join(currentDir, "..", "..", "tests")
func pathInTestsDir(pathElements []string) string {
return filepath.Join(testsDir, filepath.Join(pathElements...))
}

func getTestArgs(dirPath, outFile, outFormat string, netpols, quiet, verbose bool) InArgs {
func getTestArgs(dirPaths [][]string, outFile, outFormat string, netpols, quiet, verbose bool) InArgs {
args := InArgs{}
args.DirPaths = []string{dirPath}
args.DirPaths = []string{}
for idx := range dirPaths {
args.DirPaths = append(args.DirPaths, pathInTestsDir(dirPaths[idx]))
}
args.OutputFile = &outFile
args.OutputFormat = &outFormat
args.SynthNetpols = &netpols
Expand All @@ -169,9 +207,12 @@ func readLines(path string) ([]string, error) {

func compareFiles(expectedFile, actualFile string) (bool, error) {
expectedLines, err1 := readLines(expectedFile)
if err1 != nil {
return false, fmt.Errorf("error reading lines from file %v", err1)
}
actualLines, err2 := readLines(actualFile)
if err1 != nil || err2 != nil {
return false, errors.New("error reading lines from file")
if err2 != nil {
return false, fmt.Errorf("error reading lines from file %v", err2)
}
if len(expectedLines) != len(actualLines) {
fmt.Printf("Files line count is different: expected(%s): %d, actual(%s): %d",
Expand Down