mirror of
https://github.com/gravitational/teleport
synced 2024-10-20 17:23:22 +00:00
Enable BPF tests in CI (#10933)
This commit is contained in:
parent
dd12a7f60e
commit
c380f86bd9
|
@ -1,3 +1,5 @@
|
|||
//go:build linux
|
||||
|
||||
/*
|
||||
Copyright 2021 Gravitational, Inc.
|
||||
|
||||
|
@ -23,10 +25,12 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/artifacts"
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/changes"
|
||||
|
@ -36,8 +40,11 @@ import (
|
|||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/secrets"
|
||||
)
|
||||
|
||||
// debugFsPath is the path where debugfs should be mounted.
|
||||
const debugFsPath = "/sys/kernel/debug"
|
||||
|
||||
// main is just a stub that prints out an error message and sets a nonzero exit
|
||||
// code on failure. All of the work happens in `innerMain()`.
|
||||
// code on failure. All the work happens in `innerMain()`.
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
log.Fatalf("FAILED: %s", err.Error())
|
||||
|
@ -165,6 +172,11 @@ func run() error {
|
|||
artifacts.FindAndUpload(timeoutCtx, args.bucket, prefix, args.artifactSearchPatterns)
|
||||
}()
|
||||
|
||||
log.Printf("Mounting debugfs")
|
||||
if err := mountDebugFS(); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
log.Printf("Running unit tests...")
|
||||
err = runUnitTests(args.workspace)
|
||||
if err != nil {
|
||||
|
@ -177,13 +189,49 @@ func run() error {
|
|||
}
|
||||
|
||||
func runUnitTests(workspace string) error {
|
||||
enableTests := []string{
|
||||
"TELEPORT_ETCD_TEST=yes",
|
||||
"TELEPORT_XAUTH_TEST=yes",
|
||||
"TELEPORT_BPF_TEST=yes",
|
||||
}
|
||||
|
||||
cmd := exec.Command("make", "test")
|
||||
cmd.Dir = workspace
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = append(cmd.Env, "TELEPORT_ETCD_TEST=yes")
|
||||
cmd.Env = append(cmd.Env, "TELEPORT_XAUTH_TEST=yes")
|
||||
cmd.Env = append(cmd.Env, enableTests...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// mountDebugFS mounts debugfs at /sys/kernel/debug, so BPF test can run in GCB.
|
||||
func mountDebugFS() error {
|
||||
if isDebugFsMounted() {
|
||||
return nil
|
||||
}
|
||||
// equivalent to: mount -t debugfs none /sys/kernel/debug/
|
||||
if err := unix.Mount("debugfs", debugFsPath, "debugfs", 0, ""); err != nil {
|
||||
return trace.Wrap(err, "failed to mount debugfs")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isDebugFsMounted returns true if debugfs is mounted, false otherwise.
|
||||
func isDebugFsMounted() bool {
|
||||
mounts, err := os.ReadFile("/proc/mounts")
|
||||
if err != nil {
|
||||
log.Warningf("Failed to read /proc/mounts: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(string(mounts), "\n") {
|
||||
tokens := strings.Fields(line)
|
||||
if len(tokens) == 6 && tokens[0] == "debugfs" && tokens[1] == debugFsPath {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ require (
|
|||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27
|
||||
google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c
|
||||
)
|
||||
|
||||
|
@ -42,7 +43,6 @@ require (
|
|||
go.opencensus.io v0.23.0 // indirect
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
|
|
|
@ -57,15 +57,14 @@ func TestRootBPF(t *testing.T) {
|
|||
}
|
||||
|
||||
func (s *Suite) TestWatch(c *check.C) {
|
||||
// TODO(jakule): Find a way to run this test in CI. Disable for now to not block all BPF tests.
|
||||
c.Skip("this test always fails when running inside a CGroup/Docker")
|
||||
|
||||
// This test must be run as root and the host has to be capable of running
|
||||
// BPF programs.
|
||||
if !isRoot() {
|
||||
c.Skip("Tests for package bpf can only be run as root.")
|
||||
}
|
||||
err := IsHostCompatible()
|
||||
if err != nil {
|
||||
c.Skip(fmt.Sprintf("Tests for package bpf can not be run: %v.", err))
|
||||
}
|
||||
|
||||
// Create temporary directory where cgroup2 hierarchy will be mounted.
|
||||
dir, err := os.MkdirTemp("", "cgroup-test")
|
||||
|
@ -145,11 +144,6 @@ func (s *Suite) TestObfuscate(c *check.C) {
|
|||
c.Skip("Tests for package bpf can only be run as root.")
|
||||
return
|
||||
}
|
||||
err := IsHostCompatible()
|
||||
if err != nil {
|
||||
c.Skip(fmt.Sprintf("Tests for package bpf can not be run: %v.", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Find the programs needed to run these tests on the host.
|
||||
decoderPath, err := os_exec.LookPath("base64")
|
||||
|
@ -229,10 +223,6 @@ func (s *Suite) TestScript(c *check.C) {
|
|||
if !isRoot() {
|
||||
c.Skip("Tests for package bpf can only be run as root.")
|
||||
}
|
||||
err := IsHostCompatible()
|
||||
if err != nil {
|
||||
c.Skip(fmt.Sprintf("Tests for package bpf can not be run: %v.", err))
|
||||
}
|
||||
|
||||
// Start execsnoop.
|
||||
execsnoop, err := startExec(8192)
|
||||
|
@ -303,12 +293,6 @@ func (s *Suite) TestPrograms(c *check.C) {
|
|||
c.Skip("Tests for package bpf can only be run as root.")
|
||||
}
|
||||
|
||||
// Check that the host is capable of running BPF programs.
|
||||
err := IsHostCompatible()
|
||||
if err != nil {
|
||||
c.Skip(fmt.Sprintf("Tests for package bpf can not be run: %v.", err))
|
||||
}
|
||||
|
||||
// Start a debug server that tcpconnect will connect to.
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintln(w, "hello, world")
|
||||
|
@ -395,12 +379,6 @@ func (s *Suite) TestBPFCounter(c *check.C) {
|
|||
c.Skip("Tests for package bpf can only be run as root.")
|
||||
}
|
||||
|
||||
// Check that the host is capable of running BPF programs.
|
||||
err := IsHostCompatible()
|
||||
if err != nil {
|
||||
c.Skip(fmt.Sprintf("Tests for package bpf can not be run: %v.", err))
|
||||
}
|
||||
|
||||
counterTestBPF, err := embedFS.ReadFile("bytecode/counter_test.bpf.o")
|
||||
if err != nil {
|
||||
c.Skip(fmt.Sprintf("Tests for package bpf can not be run: %v.", err))
|
||||
|
|
|
@ -182,16 +182,13 @@ func (s *Suite) SetUpSuite(c *check.C) {
|
|||
if !isRoot() {
|
||||
c.Skip("Tests for package restrictedsession can only be run as root.")
|
||||
}
|
||||
err := bpf.IsHostCompatible()
|
||||
if err != nil {
|
||||
c.Skip(fmt.Sprintf("Tests for package restrictedsession can not be run: %v.", err))
|
||||
}
|
||||
|
||||
s.srcAddrs = map[int]string{
|
||||
4: "0.0.0.0",
|
||||
6: "::",
|
||||
}
|
||||
|
||||
var err error
|
||||
// Create temporary directory where cgroup2 hierarchy will be mounted.
|
||||
s.cgroupDir, err = os.MkdirTemp("", "cgroup-test")
|
||||
c.Assert(err, check.IsNil)
|
||||
|
@ -287,7 +284,7 @@ func (s *Suite) closeSession(c *check.C) {
|
|||
var ip4Regex = regexp.MustCompile(`^\d+\.\d+\.\d+\.\d+$`)
|
||||
|
||||
// mustParseIP parses the IP and also converts IPv4 addresses
|
||||
// to 4 byte represenetation. IPv4 mapped (into IPv6) addresses
|
||||
// to 4 byte representation. IPv4 mapped (into IPv6) addresses
|
||||
// are kept in 16 byte encoding
|
||||
func mustParseIP(addr string) net.IP {
|
||||
is4 := ip4Regex.MatchString(addr)
|
||||
|
@ -508,8 +505,8 @@ func isRoot() bool {
|
|||
return os.Geteuid() == 0
|
||||
}
|
||||
|
||||
// bpfTestEnabled returns true if BPF tests should run. Tests can be enabled by
|
||||
// setting TELEPORT_BPF_TEST environment variable to any value.
|
||||
// bpfTestEnabled returns true if BPF/LSM tests should run. Tests can be enabled by
|
||||
// setting TELEPORT_BPF_LSM_TEST environment variable to any value.
|
||||
func bpfTestEnabled() bool {
|
||||
return os.Getenv("TELEPORT_BPF_TEST") != ""
|
||||
return os.Getenv("TELEPORT_BPF_LSM_TEST") != ""
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue