Skip to content

Commit

Permalink
chore: mscope: make scopes tests more robust
Browse files Browse the repository at this point in the history
- add checkEvents generic function to check if all events are received
- add common.go with execCommand function that ensures execution of a
  command in the same cpu
- add waitForTraceeOutputEvents function to wait for tracee output
  events until buffer fills with certain number of events or
  timeout occurs
- remove do_ls_uname tester.sh function as a start to concentrate all
  scopes tests in scopes_test.go
- create syscaller tool to easily generate syscalls from the command
  line
  • Loading branch information
geyslan committed Feb 10, 2023
1 parent 061f163 commit 88ac808
Show file tree
Hide file tree
Showing 9 changed files with 568 additions and 86 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ compile_commands.json
.vagrant

# binaries and build files
dist
dist
syscaller
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ CMD_CAT ?= cat
CMD_MD5 ?= md5sum
CMD_OPA ?= opa
CMD_STATICCHECK ?= staticcheck
CMD_SYSCALLER ?= ./tests/integration/syscaller/syscaller

.check_%:
#
Expand Down Expand Up @@ -705,9 +706,20 @@ test-types: \
-coverprofile=coverage.txt \
./...

#
# syscaller (required for integration tests)
#

.PHONY: $(CMD_SYSCALLER)
$(CMD_SYSCALLER): \
| .check_$(CMD_GO)
#
$(CMD_GO) build -o $(CMD_SYSCALLER) $(dir $(CMD_SYSCALLER))

.PHONY: test-integration
test-integration: \
.checkver_$(CMD_GO) \
$(CMD_SYSCALLER) \
tracee-ebpf
#
$(GO_ENV_EBPF) \
Expand Down Expand Up @@ -813,4 +825,5 @@ clean:
$(CMD_RM) -rf $(OUTPUT_DIR)
$(CMD_RM) -f .*.md5
$(CMD_RM) -f .check*
$(CMD_RM) -f .*-pkgs*
$(CMD_RM) -f .*-pkgs*
$(CMD_RM) -f $(CMD_SYSCALLER)
49 changes: 49 additions & 0 deletions tests/integration/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package integration

import (
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"

"golang.org/x/sys/unix"
)

const cpuID = 0 // CPU to pin the process to

// execCommand executes a command pinning it to a specific CPU and returns the process and its stdout
func execCommand(fullCmd string) (*os.Process, []byte, error) {
vals := strings.Split(fullCmd, " ")

cmd := vals[0] // as separator is a space, split will always return at least one element
cmd, err := exec.LookPath(cmd)
if err != nil {
return nil, nil, err
}
if !filepath.IsAbs(cmd) {
cmd, err = filepath.Abs(cmd)
if err != nil {
return nil, nil, err
}
}

args := []string{}
if len(vals) > 1 {
args = vals[1:]
}

// set the affinity of the thread to a specific CPU,
// making sure that the events will be generated in order
cpuMask := unix.CPUSet{}
cpuMask.Set(cpuID)
unix.SchedSetaffinity(0, &cpuMask)
runtime.LockOSThread() // also wire the calling goroutine to the same CPU

c := exec.Command(cmd, args...)
stdout, err := c.Output()

runtime.UnlockOSThread()

return c.Process, stdout, err
}
79 changes: 0 additions & 79 deletions tests/integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/aquasecurity/tracee/pkg/cmd/flags"
tracee "github.com/aquasecurity/tracee/pkg/ebpf"
"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/signatures/helpers"
"github.com/aquasecurity/tracee/types/trace"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -199,48 +198,6 @@ func checkSecurityFileOpenExecve(t *testing.T, gotOutput *[]trace.Event) {
}
}

func checkScope42SecurityFileOpenLs(t *testing.T, gotOutput *[]trace.Event) {
_, err := forkAndExecFunction(doLs)
require.NoError(t, err)

waitForTraceeOutput(t, gotOutput, time.Now(), true)

for _, evt := range *gotOutput {
// ls - scope 42
assert.Equal(t, "ls", evt.ProcessName)
assert.Equal(t, uint64(1<<41), evt.MatchedScopes)
arg, err := helpers.GetTraceeArgumentByName(evt, "pathname", helpers.GetArgOps{DefaultArgs: false})
require.NoError(t, err)
assert.Contains(t, arg.Value, "integration")
}
}

// checkExecveOnScopes4And2 demands an ordered events submission
func checkExecveOnScopes4And2(t *testing.T, gotOutput *[]trace.Event) {
_, err := forkAndExecFunction(doLsUname)
require.NoError(t, err)

waitForTraceeOutput(t, gotOutput, time.Now(), true)

// check output length
require.Len(t, *gotOutput, 2)
var evts [2]trace.Event

// output should only have events with event name of execve
for i, evt := range *gotOutput {
assert.Equal(t, "sched_process_exit", evt.EventName)
evts[i] = evt
}

// ls - scope 4
assert.Equal(t, evts[0].ProcessName, "ls")
assert.Equal(t, uint64(1<<3), evts[0].MatchedScopes, "MatchedScopes")

// uname - scope 2
assert.Equal(t, evts[1].ProcessName, "uname")
assert.Equal(t, uint64(1<<1), evts[1].MatchedScopes, "MatchedScopes")
}

func checkDockerdBinaryFilter(t *testing.T, gotOutput *[]trace.Event) {
dockerdPidBytes, err := forkAndExecFunction(getDockerdPid)
require.NoError(t, err)
Expand All @@ -259,23 +216,6 @@ func checkDockerdBinaryFilter(t *testing.T, gotOutput *[]trace.Event) {
assert.Contains(t, processIds, int(dockerdPid))
}

func checkLsAndWhichBinaryFilterWithScopes(t *testing.T, gotOutput *[]trace.Event) {
var err error
_, err = forkAndExecFunction(doLs)
require.NoError(t, err)
_, err = forkAndExecFunction(doWhichLs)
require.NoError(t, err)

waitForTraceeOutput(t, gotOutput, time.Now(), true)

for _, evt := range *gotOutput {
procName := evt.ProcessName
if procName != "ls" && procName != "which" {
t.Fail()
}
}
}

func Test_EventFilters(t *testing.T) {
testCases := []struct {
name string
Expand Down Expand Up @@ -337,19 +277,6 @@ func Test_EventFilters(t *testing.T) {
filterArgs: []string{"container=new", "event!=container_create,container_remove"},
eventFunc: checkNewContainers,
},
{
name: "trace event set in a specific scope",
filterArgs: []string{"42:comm=ls", "42:event=security_file_open", "42:security_file_open.args.pathname=*integration"},
eventFunc: checkScope42SecurityFileOpenLs,
},
{
name: "trace events set in two specific scope",
filterArgs: []string{
"4:event=sched_process_exit", "4:comm=ls",
"2:event=sched_process_exit", "2:comm=uname",
},
eventFunc: checkExecveOnScopes4And2,
},
{
name: "trace only security_file_open from \"execve\" syscall",
filterArgs: []string{"event=security_file_open", "security_file_open.context.syscall=execve"},
Expand All @@ -360,11 +287,6 @@ func Test_EventFilters(t *testing.T) {
filterArgs: []string{"bin=/usr/bin/dockerd"},
eventFunc: checkDockerdBinaryFilter,
},
{
name: "trace events from ls and which binary in separate scopes",
filterArgs: []string{"1:bin=/usr/bin/ls", "2:bin=/usr/bin/which"},
eventFunc: checkLsAndWhichBinaryFilterWithScopes,
},
}

for _, tc := range testCases {
Expand Down Expand Up @@ -405,7 +327,6 @@ type testFunc string
const (
doMagicWrite testFunc = "do_magic_write"
doLs testFunc = "do_ls"
doLsUname testFunc = "do_ls_uname"
doDockerRun testFunc = "do_docker_run"
doFileOpen testFunc = "do_file_open"
getDockerdPid testFunc = "get_dockerd_pid"
Expand Down
Loading

0 comments on commit 88ac808

Please sign in to comment.