Compare commits

..

2 Commits

Author SHA1 Message Date
Antonio Ojea 40e022df81 Add integration tests for nftables package
This commit adds integration tests to the nftables package to verify
that the Go code correctly programs nftables rules. The tests use
external nftables scripts to define the expected state and compare
it with the state produced by the Go code.

Change-Id: I9c8439ee462b4882b221e6244f53379b822446dc
Signed-off-by: Antonio Ojea <aojea@google.com>
2025-01-04 01:42:45 +00:00
Antonio Ojea c308cb2197 adapt tests to avoid complains with the format
Change-Id: Ie90d72f48e42c9d896ba302685352295efacc099
Signed-off-by: Antonio Ojea <aojea@google.com>
2025-01-04 01:42:30 +00:00
7 changed files with 38 additions and 22 deletions

View File

@ -33,5 +33,5 @@ jobs:
go test ./... go test ./...
go test -c github.com/google/nftables go test -c github.com/google/nftables
sudo ./nftables.test -test.v -run_system_tests sudo ./nftables.test -test.v -run_system_tests
go test -c github.com/google/nftables/integration go test -c github.com/google/nftables/tests
sudo ./integration.test -test.v -run_system_tests sudo ./tests.test -test.v -run_system_tests

7
go.mod
View File

@ -4,14 +4,15 @@ go 1.21
require ( require (
github.com/google/go-cmp v0.6.0 github.com/google/go-cmp v0.6.0
github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 github.com/mdlayher/netlink v1.7.2
github.com/vishvananda/netlink v1.3.0 github.com/vishvananda/netlink v1.3.0
github.com/vishvananda/netns v0.0.4 github.com/vishvananda/netns v0.0.4
golang.org/x/sys v0.28.0 golang.org/x/sys v0.18.0
) )
require ( require (
github.com/josharian/native v1.1.0 // indirect
github.com/mdlayher/socket v0.5.0 // indirect github.com/mdlayher/socket v0.5.0 // indirect
golang.org/x/net v0.33.0 // indirect golang.org/x/net v0.23.0 // indirect
golang.org/x/sync v0.6.0 // indirect golang.org/x/sync v0.6.0 // indirect
) )

14
go.sum
View File

@ -1,18 +1,20 @@
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 h1:A1Cq6Ysb0GM0tpKMbdCXCIfBclan4oHk1Jb+Hrejirg= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42/go.mod h1:BB4YCPDOzfy7FniQ/lxuYQ3dgmM2cZumHbK8RpTjN2o= github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI= github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI=
github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI= github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI=
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk= github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs= github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=

View File

@ -12,11 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package integration package tests
import ( import (
"flag" "flag"
"os/exec" "os/exec"
"path/filepath"
"runtime"
"strings" "strings"
"testing" "testing"
@ -188,7 +190,11 @@ func TestNFTables(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
scriptOutput, err := applyNFTRuleset(tt.scriptPath) _, filename, _, _ := runtime.Caller(0) // Get the current file's path
filePath := filepath.Join(filepath.Dir(filename), tt.scriptPath)
t.Logf("testing script from %s", filePath)
scriptOutput, err := applyNFTScript(filePath)
if err != nil { if err != nil {
t.Fatalf("Failed to apply nftables script: %v\noutput:%s", err, scriptOutput) t.Fatalf("Failed to apply nftables script: %v\noutput:%s", err, scriptOutput)
} }
@ -197,20 +203,21 @@ func TestNFTables(t *testing.T) {
} }
// Retrieve nftables state using nft // Retrieve nftables state using nft
expectedOutput, err := listNFTRuleset() expectedOutput, err := getNFTablesRuleset()
if err != nil { if err != nil {
t.Fatalf("Failed to list nftables ruleset: %v\noutput:%s", err, expectedOutput) t.Fatalf("Failed to list nftables ruleset: %v\noutput:%s", err, expectedOutput)
} }
t.Logf("Expected output:\n%s", expectedOutput) t.Logf("Expected output:\n%s", expectedOutput)
// Program nftables using your Go code // Program nftables using your Go code
if err := flushNFTRuleset(); err != nil { err = flushNFTRuleset()
if err != nil {
t.Fatalf("Failed to flush nftables ruleset: %v", err) t.Fatalf("Failed to flush nftables ruleset: %v", err)
} }
tt.goCommands(t, c) tt.goCommands(t, c)
// Retrieve nftables state using nft // Retrieve nftables state using nft
actualOutput, err := listNFTRuleset() actualOutput, err := getNFTablesRuleset()
if err != nil { if err != nil {
t.Fatalf("Failed to list nftables ruleset: %v\noutput:%s", err, actualOutput) t.Fatalf("Failed to list nftables ruleset: %v\noutput:%s", err, actualOutput)
} }
@ -221,32 +228,38 @@ func TestNFTables(t *testing.T) {
t.Errorf("nftables ruleset mismatch:\n%s", cmp.Diff(expectedOutput, actualOutput)) t.Errorf("nftables ruleset mismatch:\n%s", cmp.Diff(expectedOutput, actualOutput))
} }
if err := flushNFTRuleset(); err != nil { err = flushNFTRuleset()
if err != nil {
t.Fatalf("Failed to flush nftables ruleset: %v", err) t.Fatalf("Failed to flush nftables ruleset: %v", err)
} }
}) })
} }
} }
func applyNFTRuleset(scriptPath string) (string, error) { func applyNFTScript(scriptPath string) (string, error) {
cmd := exec.Command("nft", "--debug=all", "-f", scriptPath) cmd := exec.Command("nft", "-f", scriptPath)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return string(out), err return string(out), err
} }
return strings.TrimSpace(string(out)), nil return normalizeOutput(string(out)), nil
} }
func listNFTRuleset() (string, error) { func getNFTablesRuleset() (string, error) {
cmd := exec.Command("nft", "list", "ruleset") cmd := exec.Command("nft", "list", "ruleset")
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return string(out), err return string(out), err
} }
return strings.TrimSpace(string(out)), nil return normalizeOutput(string(out)), nil
} }
func flushNFTRuleset() error { func flushNFTRuleset() error {
cmd := exec.Command("nft", "flush", "ruleset") cmd := exec.Command("nft", "flush", "ruleset")
return cmd.Run() return cmd.Run()
} }
func normalizeOutput(output string) string {
output = strings.TrimSpace(output)
return output
}