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

Add actuator test #20

Merged
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ golangci-lint: ## Download golangci-lint locally if necessary.

MOCKERY = $(shell pwd)/bin/mockery
mockery: ## Download mockery if necessary.
$(call go-install-tool,$(MOCKERY),github.com/vektra/mockery/v2@v2.12.3)
$(call go-install-tool,$(MOCKERY),github.com/vektra/mockery/v2@v2.14.0)

# go-get-tool will 'go get' any package $2 and install it to $1.
PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.5.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.7.0
k8s.io/api v0.24.2
k8s.io/apimachinery v0.24.2
k8s.io/client-go v0.24.2
Expand Down Expand Up @@ -45,7 +46,9 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/stretchr/objx v0.2.0 // indirect
github.com/vishvananda/netlink v1.1.1-0.20211101163509-b10eb8fe5cf6 // indirect
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
Expand Down
140 changes: 140 additions & 0 deletions pkg/tc/actuator_file_writer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package tc_test

import (
"flag"
"fmt"
"os"
"path/filepath"
"time"

"k8s.io/klog/v2"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"github.com/Mellanox/multi-networkpolicy-tc/pkg/tc"
"github.com/Mellanox/multi-networkpolicy-tc/pkg/tc/types"
"github.com/Mellanox/multi-networkpolicy-tc/pkg/utils"
)

func getLastModifiedTime(path string) time.Time {
fInfo, err := os.Lstat(path)
ExpectWithOffset(1, err).ToNot(HaveOccurred())
return fInfo.ModTime()
}

var _ = Describe("Actuator file writer tests", Ordered, func() {
var tempDir string
var logger klog.Logger
var actuator tc.Actuator

BeforeAll(func() {
// init logger
fs := flag.NewFlagSet("test-flag-set", flag.PanicOnError)
klog.InitFlags(fs)
Expect(fs.Set("v", "8")).ToNot(HaveOccurred())
logger = klog.NewKlogr().WithName("actuator-file-writer-test")
DeferCleanup(klog.Flush)
By("Logger initialized")

// create temp dir
tempDir = GinkgoT().TempDir()
By(fmt.Sprintf("Generated temp dir for test: %s", tempDir))
})

Context("Actuator file writer with bad path", func() {
It("fails to actuate on non existent path", func() {
nonExistentPath := filepath.Join(tempDir, "does", "not", "exist")
actuator = tc.NewActuatorFileWriterImpl(nonExistentPath, logger)
objs := &tc.TCObjects{
QDisc: types.NewIngressQdisc(),
}
err := actuator.Actuate(objs)
Expect(err).To(HaveOccurred())
})

It("fails to actuate on invalid path", func() {
invalidPath := ""
actuator = tc.NewActuatorFileWriterImpl(invalidPath, logger)
objs := &tc.TCObjects{
QDisc: types.NewIngressQdisc(),
}
err := actuator.Actuate(objs)
Expect(err).To(HaveOccurred())
})
})

Context("Actuator file writer with valid path", func() {
var tmpFilePath string
objs := &tc.TCObjects{
QDisc: types.NewIngressQdisc(),
Filters: []types.Filter{
types.NewFlowerFilterBuilder().WithProtocol(types.FilterProtocolIP).WithPriority(100).Build(),
},
}
expectedFileContent := `qdisc: ingress
filters:
protocol ip pref 100 flower
`

BeforeEach(func() {
tmpFilePath = filepath.Join(tempDir, "test-file")
exist, err := utils.PathExists(tmpFilePath)
Expect(err).ToNot(HaveOccurred())
Expect(exist).To(BeFalse())
actuator = tc.NewActuatorFileWriterImpl(tmpFilePath, logger)
})

AfterEach(func() {
exist, err := utils.PathExists(tmpFilePath)
Expect(err).ToNot(HaveOccurred())
if exist {
Expect(os.Remove(tmpFilePath)).ToNot(HaveOccurred())
}
})

It("Writes objects to file when file does not exist", func() {
err := actuator.Actuate(objs)
Expect(err).ToNot(HaveOccurred())

content, err := os.ReadFile(tmpFilePath)
Expect(err).ToNot(HaveOccurred())
Expect(string(content)).To(BeEquivalentTo(expectedFileContent))
})

It("updates objects in file when file exist", func() {
err := actuator.Actuate(objs)
Expect(err).ToNot(HaveOccurred())

objs.Filters = append(
objs.Filters,
types.NewFlowerFilterBuilder().WithProtocol(types.FilterProtocolAll).WithPriority(200).Build())

err = actuator.Actuate(objs)
Expect(err).ToNot(HaveOccurred())

content, err := os.ReadFile(tmpFilePath)
Expect(err).ToNot(HaveOccurred())
expectedFileContent = `qdisc: ingress
filters:
protocol ip pref 100 flower
protocol all pref 200 flower
`
Expect(string(content)).To(BeEquivalentTo(expectedFileContent))
})

It("does not update file if same objects provided", func() {
err := actuator.Actuate(objs)
Expect(err).ToNot(HaveOccurred())

firstModified := getLastModifiedTime(tmpFilePath)

err = actuator.Actuate(objs)
Expect(err).ToNot(HaveOccurred())

lastModified := getLastModifiedTime(tmpFilePath)

Expect(firstModified.Equal(lastModified)).To(BeTrue())
})
})
})
4 changes: 4 additions & 0 deletions pkg/tc/actuator_tc.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ type ActuatorTCImpl struct {
// Actuate is an implementation of Actuator interface. it applies TCObjects on the representor
// Note: it assumes all filters are in Chain 0
func (a *ActuatorTCImpl) Actuate(objects *TCObjects) error {
if objects.QDisc == nil && len(objects.Filters) > 0 {
return errors.New("Qdisc cannot be nil if Filters are provided")
}

// list qdiscs
currentQDiscs, err := a.tcApi.QDiscList()
if err != nil {
Expand Down
Loading