Skip to content

Commit

Permalink
Merge pull request #20 from adrianchiris/add-actuator-test
Browse files Browse the repository at this point in the history
Add actuator test
  • Loading branch information
ykulazhenkov authored Aug 4, 2022
2 parents 7df9dff + e63ed97 commit a5201c2
Show file tree
Hide file tree
Showing 6 changed files with 610 additions and 1 deletion.
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

0 comments on commit a5201c2

Please sign in to comment.