summaryrefslogtreecommitdiff
path: root/integrationtests
diff options
context:
space:
mode:
Diffstat (limited to 'integrationtests')
-rw-r--r--integrationtests/expectations.go16
-rw-r--r--integrationtests/family_test.go6
-rw-r--r--integrationtests/harness.go185
-rw-r--r--integrationtests/helpers_test.go7
-rw-r--r--integrationtests/iouring_test.go22
-rw-r--r--integrationtests/ipc_test.go18
-rw-r--r--integrationtests/mmap_test.go20
-rw-r--r--integrationtests/mountfs_test.go9
-rw-r--r--integrationtests/pidfd_test.go10
-rw-r--r--integrationtests/polling_test.go6
-rw-r--r--integrationtests/process_test.go6
-rw-r--r--integrationtests/retbytes_test.go6
-rw-r--r--integrationtests/security_test.go6
-rw-r--r--integrationtests/sleep_test.go7
-rw-r--r--integrationtests/socket_test.go25
15 files changed, 276 insertions, 73 deletions
diff --git a/integrationtests/expectations.go b/integrationtests/expectations.go
index 36fdf6e..04afca9 100644
--- a/integrationtests/expectations.go
+++ b/integrationtests/expectations.go
@@ -30,6 +30,7 @@ func AssertEventsPresent(t *testing.T, result TestResult, expected []ExpectedEve
}
if !matched {
t.Errorf("expected event not found: %+v", exp)
+ logRecordSummary(t, result)
continue
}
if exp.MinCount > 0 && totalCount < exp.MinCount {
@@ -39,6 +40,19 @@ func AssertEventsPresent(t *testing.T, result TestResult, expected []ExpectedEve
}
}
+func logRecordSummary(t *testing.T, result TestResult) {
+ t.Helper()
+ limit := 20
+ if len(result.Records) < limit {
+ limit = len(result.Records)
+ }
+ t.Logf("captured %d records; first %d:", len(result.Records), limit)
+ for i := 0; i < limit; i++ {
+ rec := result.Records[i]
+ t.Logf(" tracepoint=%s comm=%q pid=%d path=%q count=%d", rec.TraceID.String(), rec.Comm, rec.Pid, rec.Path, rec.Cnt.Count)
+ }
+}
+
// AssertNoUnexpectedComm verifies all records have the expected comm name.
// Records with empty comm are skipped because BPF may capture events before
// the process name is set in the task struct.
@@ -109,7 +123,7 @@ func matchesExpectation(rec flamegraph.IterRecord, exp ExpectedEvent) bool {
if exp.Tracepoint != "" && !strings.Contains(rec.TraceID.String(), exp.Tracepoint) {
return false
}
- if exp.Comm != "" && rec.Comm != exp.Comm {
+ if exp.Comm != "" && rec.Comm != "" && rec.Comm != exp.Comm {
return false
}
return true
diff --git a/integrationtests/family_test.go b/integrationtests/family_test.go
index 7558bfa..bfb0cf6 100644
--- a/integrationtests/family_test.go
+++ b/integrationtests/family_test.go
@@ -15,10 +15,12 @@ const (
familyWorkloadStartupEnv = "IOR_WORKLOAD_STARTUP_DELAY_MS=1000"
)
+var familyMixedTraceArgs = []string{"-trace-syscalls", "openat,write,mmap,munmap,pipe2,socketpair,getpid,sched_yield,nanosleep"}
+
func TestFamilyParquetRecordingAndAggregation(t *testing.T) {
h := newTestHarness(t)
h.WorkloadEnv = []string{familyWorkloadStartupEnv}
- path, pid, err := h.RunParquet("family-mixed", familyParquetDuration)
+ path, pid, err := h.RunParquetWithIorArgs("family-mixed", familyParquetDuration, familyMixedTraceArgs)
if err != nil {
t.Fatalf("run family-mixed parquet scenario: %v", err)
}
@@ -54,7 +56,7 @@ func TestFamilyParquetRecordingAndAggregation(t *testing.T) {
}
for syscall := range expectedSyscallFamilies {
if !seenSyscalls[syscall] {
- t.Fatalf("expected traced syscall %q in parquet rows", syscall)
+ t.Fatalf("expected traced syscall %q in parquet rows; saw syscalls: %+v", syscall, seenSyscalls)
}
}
diff --git a/integrationtests/harness.go b/integrationtests/harness.go
index b69e5d2..6633332 100644
--- a/integrationtests/harness.go
+++ b/integrationtests/harness.go
@@ -2,6 +2,7 @@ package integrationtests
import (
"bufio"
+ "bytes"
"fmt"
"io"
"os"
@@ -9,13 +10,18 @@ import (
"path/filepath"
"strconv"
"strings"
+ "sync"
"time"
)
const (
workloadStartupTimeout = 5 * time.Second
+ iorReadyTimeout = 30 * time.Second
+ iorReadySettleDelay = time.Second
iorShutdownGrace = 30 * time.Second
bpfObjectOverrideEnv = "IOR_BPF_OBJECT"
+ workloadStartupFileEnv = "IOR_WORKLOAD_STARTUP_FILE"
+ iorReadyLine = "Probing for "
)
// TestHarness orchestrates integration tests by starting an ior trace
@@ -37,17 +43,21 @@ func (h *TestHarness) Run(scenario string, duration int) (TestResult, int, error
// RunWithIorArgs behaves like Run but forwards additional args to ior.
func (h *TestHarness) RunWithIorArgs(scenario string, duration int, extraIorArgs []string) (TestResult, int, error) {
- workloadCmd, workloadPID, err := h.startWorkload(scenario)
+ startupFile := h.workloadStartupFile(scenario)
+ workloadCmd, workloadPID, workloadStderr, err := h.startWorkload(scenario, startupFile)
if err != nil {
return TestResult{}, 0, err
}
- iorCmd, err := h.startIor(workloadPID, scenario, duration, extraIorArgs)
+ iorCmd, readyCh, err := h.startIorForRun(workloadPID, scenario, duration, extraIorArgs)
if err != nil {
workloadCmd.Process.Kill()
workloadCmd.Wait()
return TestResult{}, workloadPID, err
}
+ if err := releaseWorkloadWhenIorReady(startupFile, workloadCmd, iorCmd, readyCh); err != nil {
+ return TestResult{}, workloadPID, err
+ }
workloadErr, iorErr := waitBoth(workloadCmd, iorCmd, duration, iorShutdownGrace)
@@ -55,7 +65,7 @@ func (h *TestHarness) RunWithIorArgs(scenario string, duration int, extraIorArgs
return TestResult{}, workloadPID, fmt.Errorf("ior: %w", iorErr)
}
if workloadErr != nil {
- return TestResult{}, workloadPID, fmt.Errorf("workload: %w", workloadErr)
+ return TestResult{}, workloadPID, workloadCommandError(workloadErr, workloadStderr.String())
}
iorFile, err := findIorZstFile(h.OutputDir, scenario)
@@ -74,43 +84,65 @@ func (h *TestHarness) RunWithIorArgs(scenario string, duration int, extraIorArgs
// RunParquet executes a scenario in headless Parquet mode and returns the
// recorded Parquet path.
func (h *TestHarness) RunParquet(scenario string, duration int) (string, int, error) {
+ return h.RunParquetWithIorArgs(scenario, duration, nil)
+}
+
+// RunParquetWithIorArgs behaves like RunParquet but forwards additional args
+// to ior.
+func (h *TestHarness) RunParquetWithIorArgs(scenario string, duration int, extraIorArgs []string) (string, int, error) {
parquetPath := filepath.Join(h.OutputDir, scenario+".parquet")
- workloadCmd, workloadPID, err := h.startWorkload(scenario)
+ startupFile := h.workloadStartupFile(scenario)
+ workloadCmd, workloadPID, workloadStderr, err := h.startWorkload(scenario, startupFile)
if err != nil {
return "", 0, err
}
- iorCmd, err := h.startIorParquet(workloadPID, parquetPath, duration)
+ iorCmd, readyCh, err := h.startIorParquetForRun(workloadPID, parquetPath, duration, extraIorArgs)
if err != nil {
workloadCmd.Process.Kill()
workloadCmd.Wait()
return "", workloadPID, err
}
+ if err := releaseWorkloadWhenIorReady(startupFile, workloadCmd, iorCmd, readyCh); err != nil {
+ return "", workloadPID, err
+ }
workloadErr, iorErr := waitBoth(workloadCmd, iorCmd, duration, iorShutdownGrace)
if iorErr != nil {
return "", workloadPID, fmt.Errorf("ior: %w", iorErr)
}
if workloadErr != nil {
- return "", workloadPID, fmt.Errorf("workload: %w", workloadErr)
+ return "", workloadPID, workloadCommandError(workloadErr, workloadStderr.String())
}
return parquetPath, workloadPID, nil
}
-func (h *TestHarness) startWorkload(scenario string) (*exec.Cmd, int, error) {
+func (h *TestHarness) workloadStartupFile(scenario string) string {
+ if filepath.Base(h.WorkloadBinary) != "ioworkload" {
+ return ""
+ }
+ return filepath.Join(h.OutputDir, scenario+".startup")
+}
+
+func (h *TestHarness) startWorkload(scenario, startupFile string) (*exec.Cmd, int, *bytes.Buffer, error) {
cmd := exec.Command(h.WorkloadBinary, "--scenario="+scenario)
- cmd.Stderr = os.Stderr
- if len(h.WorkloadEnv) > 0 {
+ stderr := &bytes.Buffer{}
+ cmd.Stderr = io.MultiWriter(os.Stderr, stderr)
+ if len(h.WorkloadEnv) > 0 || startupFile != "" {
cmd.Env = append(os.Environ(), h.WorkloadEnv...)
+ if startupFile != "" {
+ os.Remove(startupFile) //nolint:errcheck
+ cmd.Env = append(cmd.Env, workloadStartupFileEnv+"="+startupFile)
+ }
}
stdout, err := cmd.StdoutPipe()
if err != nil {
- return nil, 0, fmt.Errorf("workload stdout pipe: %w", err)
+ return nil, 0, nil, fmt.Errorf("workload stdout pipe: %w", err)
}
if err := cmd.Start(); err != nil {
- return nil, 0, fmt.Errorf("start workload: %w", err)
+ return nil, 0, nil, fmt.Errorf("start workload: %w", err)
}
pidCh := make(chan int, 1)
@@ -138,18 +170,26 @@ func (h *TestHarness) startWorkload(scenario string) (*exec.Cmd, int, error) {
select {
case pid := <-pidCh:
- return cmd, pid, nil
+ return cmd, pid, stderr, nil
case err := <-errCh:
cmd.Process.Kill()
cmd.Wait()
- return nil, 0, err
+ return nil, 0, nil, err
case <-startupTimer.C:
cmd.Process.Kill()
cmd.Wait()
- return nil, 0, fmt.Errorf("timeout waiting for workload PID")
+ return nil, 0, nil, fmt.Errorf("timeout waiting for workload PID")
}
}
+func workloadCommandError(err error, stderr string) error {
+ stderr = strings.TrimSpace(stderr)
+ if stderr == "" {
+ return fmt.Errorf("workload: %w", err)
+ }
+ return fmt.Errorf("workload: %w: %s", err, stderr)
+}
+
func (h *TestHarness) startIor(pid int, scenario string, duration int, extraArgs []string) (*exec.Cmd, error) {
args := []string{
"-pid", strconv.Itoa(pid),
@@ -161,15 +201,37 @@ func (h *TestHarness) startIor(pid int, scenario string, duration int, extraArgs
return h.startIorArgs(args)
}
-func (h *TestHarness) startIorParquet(pid int, parquetPath string, duration int) (*exec.Cmd, error) {
+func (h *TestHarness) startIorForRun(pid int, scenario string, duration int, extraArgs []string) (*exec.Cmd, <-chan error, error) {
+ args := []string{
+ "-pid", strconv.Itoa(pid),
+ "-flamegraph",
+ "-name", scenario,
+ "-duration", strconv.Itoa(duration),
+ }
+ args = append(args, extraArgs...)
+ return h.startIorArgsWithReady(args)
+}
+
+func (h *TestHarness) startIorParquet(pid int, parquetPath string, duration int, extraArgs []string) (*exec.Cmd, error) {
args := []string{
"-pid", strconv.Itoa(pid),
"-parquet", parquetPath,
"-duration", strconv.Itoa(duration),
}
+ args = append(args, extraArgs...)
return h.startIorArgs(args)
}
+func (h *TestHarness) startIorParquetForRun(pid int, parquetPath string, duration int, extraArgs []string) (*exec.Cmd, <-chan error, error) {
+ args := []string{
+ "-pid", strconv.Itoa(pid),
+ "-parquet", parquetPath,
+ "-duration", strconv.Itoa(duration),
+ }
+ args = append(args, extraArgs...)
+ return h.startIorArgsWithReady(args)
+}
+
func (h *TestHarness) startIorArgs(args []string) (*exec.Cmd, error) {
cmd := exec.Command(h.IorBinary, args...)
cmd.Dir = h.OutputDir
@@ -185,6 +247,99 @@ func (h *TestHarness) startIorArgs(args []string) (*exec.Cmd, error) {
return cmd, nil
}
+func (h *TestHarness) startIorArgsWithReady(args []string) (*exec.Cmd, <-chan error, error) {
+ cmd := exec.Command(h.IorBinary, args...)
+ cmd.Dir = h.OutputDir
+ if h.BpfObject != "" {
+ cmd.Env = append(os.Environ(), bpfObjectOverrideEnv+"="+h.BpfObject)
+ }
+
+ stdout, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, nil, fmt.Errorf("ior stdout pipe: %w", err)
+ }
+ stderr, err := cmd.StderrPipe()
+ if err != nil {
+ return nil, nil, fmt.Errorf("ior stderr pipe: %w", err)
+ }
+
+ if err := cmd.Start(); err != nil {
+ return nil, nil, fmt.Errorf("start ior: %w", err)
+ }
+
+ readyCh := make(chan error, 1)
+ var once sync.Once
+ signalReady := func(err error) {
+ once.Do(func() {
+ readyCh <- err
+ close(readyCh)
+ })
+ }
+
+ var wg sync.WaitGroup
+ wg.Add(2)
+ go scanIorOutput(stdout, os.Stdout, signalReady, &wg)
+ go scanIorOutput(stderr, os.Stderr, signalReady, &wg)
+ go func() {
+ wg.Wait()
+ signalReady(fmt.Errorf("ior exited before readiness line"))
+ }()
+
+ return cmd, readyCh, nil
+}
+
+func scanIorOutput(r io.Reader, w io.Writer, signalReady func(error), wg *sync.WaitGroup) {
+ defer wg.Done()
+ scanner := bufio.NewScanner(r)
+ for scanner.Scan() {
+ line := scanner.Text()
+ fmt.Fprintln(w, line)
+ if strings.Contains(line, iorReadyLine) {
+ signalReady(nil)
+ }
+ }
+ if err := scanner.Err(); err != nil {
+ signalReady(fmt.Errorf("read ior output: %w", err))
+ }
+}
+
+func releaseWorkloadWhenIorReady(startupFile string, workloadCmd, iorCmd *exec.Cmd, readyCh <-chan error) error {
+ if startupFile == "" {
+ return nil
+ }
+
+ timer := time.NewTimer(iorReadyTimeout)
+ defer stopAndDrainTimer(timer)
+
+ select {
+ case err := <-readyCh:
+ if err != nil {
+ killAndWait(workloadCmd)
+ killAndWait(iorCmd)
+ return fmt.Errorf("wait for ior readiness: %w", err)
+ }
+ time.Sleep(iorReadySettleDelay)
+ if err := os.WriteFile(startupFile, []byte("ready\n"), 0o600); err != nil {
+ killAndWait(workloadCmd)
+ killAndWait(iorCmd)
+ return fmt.Errorf("release workload: %w", err)
+ }
+ return nil
+ case <-timer.C:
+ killAndWait(workloadCmd)
+ killAndWait(iorCmd)
+ return fmt.Errorf("timeout waiting for ior readiness")
+ }
+}
+
+func killAndWait(cmd *exec.Cmd) {
+ if cmd == nil || cmd.Process == nil {
+ return
+ }
+ cmd.Process.Kill() //nolint:errcheck
+ cmd.Wait() //nolint:errcheck
+}
+
// waitBoth waits for both the workload and ior commands concurrently.
// If ior does not finish within duration + grace period, it is killed.
func waitBoth(workloadCmd, iorCmd *exec.Cmd, duration int, grace time.Duration) (workloadErr, iorErr error) {
diff --git a/integrationtests/helpers_test.go b/integrationtests/helpers_test.go
index 6ef7ba7..64a4312 100644
--- a/integrationtests/helpers_test.go
+++ b/integrationtests/helpers_test.go
@@ -52,9 +52,14 @@ func runScenario(t *testing.T, scenario string, expected []ExpectedEvent) {
func runScenarioResult(t *testing.T, scenario string, expected []ExpectedEvent) (TestResult, int) {
t.Helper()
+ return runScenarioResultWithIorArgs(t, scenario, expected, nil)
+}
+
+func runScenarioResultWithIorArgs(t *testing.T, scenario string, expected []ExpectedEvent, extraIorArgs []string) (TestResult, int) {
+ t.Helper()
enableParallelIfRequested(t)
h := newTestHarness(t)
- result, pid, err := h.Run(scenario, defaultDuration)
+ result, pid, err := h.RunWithIorArgs(scenario, defaultDuration, extraIorArgs)
if err != nil {
t.Fatalf("run scenario %s: %v", scenario, err)
}
diff --git a/integrationtests/iouring_test.go b/integrationtests/iouring_test.go
index 02d7a16..8ff59ee 100644
--- a/integrationtests/iouring_test.go
+++ b/integrationtests/iouring_test.go
@@ -2,52 +2,54 @@ package integrationtests
import "testing"
+var iouringTraceArgs = []string{"-trace-syscalls", "io_uring_setup,io_uring_enter,io_uring_register,close"}
+
func TestIouringSetup(t *testing.T) {
- runScenario(t, "iouring-setup", []ExpectedEvent{
+ runScenarioResultWithIorArgs(t, "iouring-setup", []ExpectedEvent{
{
Tracepoint: "enter_io_uring_setup",
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, iouringTraceArgs)
}
func TestIouringEnter(t *testing.T) {
- runScenario(t, "iouring-enter", []ExpectedEvent{
+ runScenarioResultWithIorArgs(t, "iouring-enter", []ExpectedEvent{
{
Tracepoint: "enter_io_uring_enter",
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, iouringTraceArgs)
}
func TestIouringRegister(t *testing.T) {
- runScenario(t, "iouring-register", []ExpectedEvent{
+ runScenarioResultWithIorArgs(t, "iouring-register", []ExpectedEvent{
{
Tracepoint: "enter_io_uring_register",
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, iouringTraceArgs)
}
func TestIouringEnterEbadf(t *testing.T) {
- runScenario(t, "iouring-enter-ebadf", []ExpectedEvent{
+ runScenarioResultWithIorArgs(t, "iouring-enter-ebadf", []ExpectedEvent{
{
Tracepoint: "enter_io_uring_enter",
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, iouringTraceArgs)
}
func TestIouringRegisterEbadf(t *testing.T) {
- runScenario(t, "iouring-register-ebadf", []ExpectedEvent{
+ runScenarioResultWithIorArgs(t, "iouring-register-ebadf", []ExpectedEvent{
{
Tracepoint: "enter_io_uring_register",
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, iouringTraceArgs)
}
diff --git a/integrationtests/ipc_test.go b/integrationtests/ipc_test.go
index c48abb8..5672bbe 100644
--- a/integrationtests/ipc_test.go
+++ b/integrationtests/ipc_test.go
@@ -7,11 +7,13 @@ import (
const mqPayloadLen = uint64(14)
+var ipcDescriptorTraceArgs = []string{"-trace-syscalls", "pipe,pipe2,eventfd,eventfd2,close"}
+
func TestPipeBasic(t *testing.T) {
- result, _ := runScenarioResult(t, "pipe-basic", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "pipe-basic", []ExpectedEvent{
{Tracepoint: "enter_pipe", MinCount: 1},
{Tracepoint: "enter_close", MinCount: 2},
- })
+ }, ipcDescriptorTraceArgs)
assertTracepointPathPrefix(t, result, "enter_pipe", "pipe:")
if got := totalTracepointPathCount(result, "enter_close", "pipe:"); got < 2 {
@@ -20,10 +22,10 @@ func TestPipeBasic(t *testing.T) {
}
func TestPipe2Basic(t *testing.T) {
- result, _ := runScenarioResult(t, "pipe2-basic", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "pipe2-basic", []ExpectedEvent{
{Tracepoint: "enter_pipe2", MinCount: 1},
{Tracepoint: "enter_close", MinCount: 2},
- })
+ }, ipcDescriptorTraceArgs)
assertTracepointPathPrefix(t, result, "enter_pipe2", "pipe:")
if got := totalTracepointPathCount(result, "enter_close", "pipe:"); got < 2 {
@@ -32,20 +34,20 @@ func TestPipe2Basic(t *testing.T) {
}
func TestEventfdBasic(t *testing.T) {
- result, _ := runScenarioResult(t, "eventfd-basic", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "eventfd-basic", []ExpectedEvent{
{Tracepoint: "enter_eventfd", MinCount: 1},
{Tracepoint: "enter_close", MinCount: 1},
- })
+ }, ipcDescriptorTraceArgs)
assertTracepointPathPrefix(t, result, "enter_eventfd", "eventfd:")
assertTracepointPathPrefix(t, result, "enter_close", "eventfd:")
}
func TestEventfd2Basic(t *testing.T) {
- result, _ := runScenarioResult(t, "eventfd2-basic", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "eventfd2-basic", []ExpectedEvent{
{Tracepoint: "enter_eventfd2", MinCount: 1},
{Tracepoint: "enter_close", MinCount: 1},
- })
+ }, ipcDescriptorTraceArgs)
assertTracepointPathPrefix(t, result, "enter_eventfd2", "eventfd:")
assertTracepointPathPrefix(t, result, "enter_close", "eventfd:")
diff --git a/integrationtests/mmap_test.go b/integrationtests/mmap_test.go
index 9d1b3ad..74eb14e 100644
--- a/integrationtests/mmap_test.go
+++ b/integrationtests/mmap_test.go
@@ -9,19 +9,21 @@ const (
mmapMinAddressSpaceBytesTotal = mmapScenarioAddressSpaceBytes * 2
)
+var mmapTraceArgs = []string{"-trace-syscalls", "openat,write,close,mmap,msync,mremap,munmap"}
+
func TestMmapBasic(t *testing.T) {
- runScenario(t, "mmap-basic", []ExpectedEvent{
+ runScenarioResultWithIorArgs(t, "mmap-basic", []ExpectedEvent{
{
PathContains: "mmapfile.txt",
Tracepoint: "enter_mmap",
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, mmapTraceArgs)
}
func TestMmapMsyncSync(t *testing.T) {
- runScenario(t, "mmap-msync-sync", []ExpectedEvent{
+ runScenarioResultWithIorArgs(t, "mmap-msync-sync", []ExpectedEvent{
{
PathContains: "msyncfile.txt",
Tracepoint: "enter_mmap",
@@ -33,11 +35,11 @@ func TestMmapMsyncSync(t *testing.T) {
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, mmapTraceArgs)
}
func TestMmapMsyncInvalidFlags(t *testing.T) {
- runScenario(t, "mmap-msync-invalid-flags", []ExpectedEvent{
+ runScenarioResultWithIorArgs(t, "mmap-msync-invalid-flags", []ExpectedEvent{
{
PathContains: "msyncinvalidfile.txt",
Tracepoint: "enter_mmap",
@@ -49,11 +51,11 @@ func TestMmapMsyncInvalidFlags(t *testing.T) {
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, mmapTraceArgs)
}
func TestMmapMremapMunmap(t *testing.T) {
- result, _ := runScenarioResult(t, "mmap-mremap-munmap", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "mmap-mremap-munmap", []ExpectedEvent{
{
Tracepoint: "enter_mremap",
Comm: "ioworkload",
@@ -64,7 +66,7 @@ func TestMmapMremapMunmap(t *testing.T) {
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, mmapTraceArgs)
assertEventBytesEqual(t, result, ExpectedEvent{
Tracepoint: "enter_mremap",
@@ -79,7 +81,7 @@ func TestMmapMremapMunmap(t *testing.T) {
func TestMmapMremapMunmapAddressSpaceBytesInParquet(t *testing.T) {
h := newTestHarness(t)
h.WorkloadEnv = []string{mmapWorkloadStartupEnv}
- path, pid, err := h.RunParquet("mmap-mremap-munmap", mmapParquetDuration)
+ path, pid, err := h.RunParquetWithIorArgs("mmap-mremap-munmap", mmapParquetDuration, mmapTraceArgs)
if err != nil {
t.Fatalf("run mmap-mremap-munmap parquet scenario: %v", err)
}
diff --git a/integrationtests/mountfs_test.go b/integrationtests/mountfs_test.go
index 77f0009..ff783e7 100644
--- a/integrationtests/mountfs_test.go
+++ b/integrationtests/mountfs_test.go
@@ -2,8 +2,13 @@ package integrationtests
import "testing"
+var mountfsTraceArgs = []string{
+ "-trace-syscalls",
+ "mount,umount,move_mount,fsmount,pivot_root,quotactl,statmount,listmount,listns,swapon,swapoff",
+}
+
func TestMountFsManagementSyscalls(t *testing.T) {
- runScenario(t, "mountfs-management", []ExpectedEvent{
+ runScenarioResultWithIorArgs(t, "mountfs-management", []ExpectedEvent{
{Tracepoint: "enter_mount", MinCount: 1},
{Tracepoint: "enter_umount", MinCount: 1},
{Tracepoint: "enter_move_mount", MinCount: 1},
@@ -15,5 +20,5 @@ func TestMountFsManagementSyscalls(t *testing.T) {
{Tracepoint: "enter_listns", MinCount: 1},
{Tracepoint: "enter_swapon", MinCount: 1},
{Tracepoint: "enter_swapoff", MinCount: 1},
- })
+ }, mountfsTraceArgs)
}
diff --git a/integrationtests/pidfd_test.go b/integrationtests/pidfd_test.go
index d742078..6116035 100644
--- a/integrationtests/pidfd_test.go
+++ b/integrationtests/pidfd_test.go
@@ -2,23 +2,25 @@ package integrationtests
import "testing"
+var pidfdTraceArgs = []string{"-trace-syscalls", "pidfd_open,pidfd_getfd,openat,write,close"}
+
func TestPidfdGetfdSuccess(t *testing.T) {
- runScenario(t, "pidfd-getfd-success", []ExpectedEvent{
+ runScenarioResultWithIorArgs(t, "pidfd-getfd-success", []ExpectedEvent{
{
PathContains: "pidfd-getfd-source.txt",
Tracepoint: "enter_pidfd_getfd",
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, pidfdTraceArgs)
}
func TestPidfdGetfdFailure(t *testing.T) {
- runScenario(t, "pidfd-getfd-failure", []ExpectedEvent{
+ runScenarioResultWithIorArgs(t, "pidfd-getfd-failure", []ExpectedEvent{
{
Tracepoint: "enter_pidfd_getfd",
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, pidfdTraceArgs)
}
diff --git a/integrationtests/polling_test.go b/integrationtests/polling_test.go
index a09cab2..d6b520c 100644
--- a/integrationtests/polling_test.go
+++ b/integrationtests/polling_test.go
@@ -10,10 +10,12 @@ const (
pollingWorkloadStartupEnv = "IOR_WORKLOAD_STARTUP_DELAY_MS=1000"
)
+var pollingTraceArgs = []string{"-trace-syscalls", "epoll_ctl,epoll_wait,epoll_pwait,epoll_pwait2,poll,ppoll,select,pselect6"}
+
func TestPollingEpollTracepoints(t *testing.T) {
h := newTestHarness(t)
h.WorkloadEnv = []string{pollingWorkloadStartupEnv}
- result, pid, err := h.Run("polling-epoll", defaultDuration)
+ result, pid, err := h.RunWithIorArgs("polling-epoll", defaultDuration, pollingTraceArgs)
if err != nil {
t.Fatalf("run scenario polling-epoll: %v", err)
}
@@ -38,7 +40,7 @@ func TestPollingEpollTracepoints(t *testing.T) {
func TestPollingEpollReadyCountInParquet(t *testing.T) {
h := newTestHarness(t)
h.WorkloadEnv = []string{pollingWorkloadStartupEnv}
- path, pid, err := h.RunParquet("polling-epoll", pollingParquetDuration)
+ path, pid, err := h.RunParquetWithIorArgs("polling-epoll", pollingParquetDuration, pollingTraceArgs)
if err != nil {
t.Fatalf("run polling-epoll parquet scenario: %v", err)
}
diff --git a/integrationtests/process_test.go b/integrationtests/process_test.go
index e9cd739..291187d 100644
--- a/integrationtests/process_test.go
+++ b/integrationtests/process_test.go
@@ -2,8 +2,10 @@ package integrationtests
import "testing"
+var processExecTraceArgs = []string{"-trace-syscalls", "execve,execveat"}
+
func TestProcessExecLifecycle(t *testing.T) {
- result, _ := runScenarioResult(t, "process-exec-lifecycle", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "process-exec-lifecycle", []ExpectedEvent{
{
Tracepoint: "enter_execve",
PathContains: "ior-missing-execve-only",
@@ -16,7 +18,7 @@ func TestProcessExecLifecycle(t *testing.T) {
Comm: "ioworkload",
MinCount: 1,
},
- })
+ }, processExecTraceArgs)
assertEventDurationPositive(t, result, ExpectedEvent{
Tracepoint: "enter_execve",
diff --git a/integrationtests/retbytes_test.go b/integrationtests/retbytes_test.go
index c6f06d8..4baed9e 100644
--- a/integrationtests/retbytes_test.go
+++ b/integrationtests/retbytes_test.go
@@ -2,10 +2,12 @@ package integrationtests
import "testing"
+var retbytesTraceArgs = []string{"-trace-syscalls", "sendto,recvfrom,sendmsg,recvmsg,sendmmsg,recvmmsg,sendfile64,splice,tee,process_vm_writev,process_vm_readv,socketpair,pipe2,openat,write,read,close,lseek,fcntl,unlinkat,mkdirat,getdents64"}
+
func TestRetbytesPhaseA(t *testing.T) {
const payloadLen = uint64(18)
- result, _ := runScenarioResult(t, "retbytes-phase-a", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "retbytes-phase-a", []ExpectedEvent{
{Tracepoint: "enter_sendto", Comm: "ioworkload", MinCount: 1},
{Tracepoint: "enter_recvfrom", Comm: "ioworkload", MinCount: 1},
{Tracepoint: "enter_sendmsg", Comm: "ioworkload", MinCount: 1},
@@ -17,7 +19,7 @@ func TestRetbytesPhaseA(t *testing.T) {
{Tracepoint: "enter_tee", Comm: "ioworkload", MinCount: 1},
{Tracepoint: "enter_process_vm_writev", Comm: "ioworkload", MinCount: 1},
{Tracepoint: "enter_process_vm_readv", Comm: "ioworkload", MinCount: 1},
- })
+ }, retbytesTraceArgs)
for _, tracepoint := range []string{
"enter_sendto",
diff --git a/integrationtests/security_test.go b/integrationtests/security_test.go
index a705a16..5b6e657 100644
--- a/integrationtests/security_test.go
+++ b/integrationtests/security_test.go
@@ -5,14 +5,16 @@ import (
"testing"
)
+var securityTraceArgs = []string{"-trace-syscalls", "keyctl,add_key,request_key,ptrace,perf_event_open,close"}
+
func TestSecurityKeysPtracePerf(t *testing.T) {
- result, _ := runScenarioResult(t, "security-keys-ptrace-perf", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "security-keys-ptrace-perf", []ExpectedEvent{
{Tracepoint: "enter_keyctl", Comm: "ioworkload", MinCount: 1},
{Tracepoint: "enter_add_key", Comm: "ioworkload", MinCount: 1},
{Tracepoint: "enter_request_key", Comm: "ioworkload", MinCount: 1},
{Tracepoint: "enter_ptrace", Comm: "ioworkload", MinCount: 1},
{Tracepoint: "enter_perf_event_open", Comm: "ioworkload", MinCount: 1},
- })
+ }, securityTraceArgs)
// Key and ptrace operations are not fd/path based and should stay untracked.
assertTracepointPathPrefix(t, result, "enter_keyctl", "N:file")
diff --git a/integrationtests/sleep_test.go b/integrationtests/sleep_test.go
index a465420..fbd93a7 100644
--- a/integrationtests/sleep_test.go
+++ b/integrationtests/sleep_test.go
@@ -7,10 +7,12 @@ const (
sleepWorkloadStartupEnv = "IOR_WORKLOAD_STARTUP_DELAY_MS=1000"
)
+var sleepTraceArgs = []string{"-trace-families", "Time"}
+
func TestSleepTracepoints(t *testing.T) {
h := newTestHarness(t)
h.WorkloadEnv = []string{sleepWorkloadStartupEnv}
- result, pid, err := h.Run("sleep-syscalls", defaultDuration)
+ result, pid, err := h.RunWithIorArgs("sleep-syscalls", defaultDuration, sleepTraceArgs)
if err != nil {
t.Fatalf("run scenario sleep-syscalls: %v", err)
}
@@ -26,7 +28,7 @@ func TestSleepTracepoints(t *testing.T) {
func TestSleepRequestedTimespecInParquet(t *testing.T) {
h := newTestHarness(t)
h.WorkloadEnv = []string{sleepWorkloadStartupEnv}
- path, pid, err := h.RunParquet("sleep-syscalls", sleepParquetDuration)
+ path, pid, err := h.RunParquetWithIorArgs("sleep-syscalls", sleepParquetDuration, sleepTraceArgs)
if err != nil {
t.Fatalf("run sleep-syscalls parquet scenario: %v", err)
}
@@ -64,4 +66,3 @@ func TestSleepRequestedTimespecInParquet(t *testing.T) {
t.Fatal("expected clock_nanosleep row with RequestedSleepNS=3000000")
}
}
-
diff --git a/integrationtests/socket_test.go b/integrationtests/socket_test.go
index 059d339..a5cd4f6 100644
--- a/integrationtests/socket_test.go
+++ b/integrationtests/socket_test.go
@@ -5,8 +5,13 @@ import (
"testing"
)
+var socketTraceArgs = []string{
+ "-trace-syscalls",
+ "socket,socketpair,bind,listen,accept4,accept,connect,shutdown,getsockname,getpeername,setsockopt,getsockopt,close",
+}
+
func TestSocketBasic(t *testing.T) {
- result, _ := runScenarioResult(t, "socket-basic", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "socket-basic", []ExpectedEvent{
{
Tracepoint: "enter_socket",
MinCount: 1,
@@ -15,14 +20,14 @@ func TestSocketBasic(t *testing.T) {
Tracepoint: "enter_close",
MinCount: 1,
},
- })
+ }, socketTraceArgs)
assertTracepointPathPrefix(t, result, "enter_socket", "socket:1:")
assertTracepointPathPrefix(t, result, "enter_close", "socket:1:")
}
func TestSocketpairBasic(t *testing.T) {
- result, _ := runScenarioResult(t, "socketpair-basic", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "socketpair-basic", []ExpectedEvent{
{
Tracepoint: "enter_socketpair",
MinCount: 1,
@@ -31,7 +36,7 @@ func TestSocketpairBasic(t *testing.T) {
Tracepoint: "enter_close",
MinCount: 2,
},
- })
+ }, socketTraceArgs)
assertTracepointPathPrefix(t, result, "enter_socketpair", "socket:1:")
if got := totalTracepointPathCount(result, "enter_close", "socket:1:"); got < 2 {
@@ -40,13 +45,13 @@ func TestSocketpairBasic(t *testing.T) {
}
func TestSocketAcceptLifecycle(t *testing.T) {
- result, _ := runScenarioResult(t, "socket-accept-lifecycle", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "socket-accept-lifecycle", []ExpectedEvent{
{Tracepoint: "enter_bind", MinCount: 1},
{Tracepoint: "enter_connect", MinCount: 1},
{Tracepoint: "enter_listen", MinCount: 1},
{Tracepoint: "enter_accept4", MinCount: 1},
{Tracepoint: "enter_shutdown", MinCount: 1},
- })
+ }, socketTraceArgs)
assertTracepointPathPrefix(t, result, "enter_bind", "socket:1:")
assertTracepointPathPrefix(t, result, "enter_connect", "socket:1:")
@@ -56,13 +61,13 @@ func TestSocketAcceptLifecycle(t *testing.T) {
}
func TestSocketAcceptLifecyclePlain(t *testing.T) {
- result, _ := runScenarioResult(t, "socket-accept-lifecycle-plain", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "socket-accept-lifecycle-plain", []ExpectedEvent{
{Tracepoint: "enter_bind", MinCount: 1},
{Tracepoint: "enter_connect", MinCount: 1},
{Tracepoint: "enter_listen", MinCount: 1},
{Tracepoint: "enter_accept", MinCount: 1},
{Tracepoint: "enter_shutdown", MinCount: 1},
- })
+ }, socketTraceArgs)
assertTracepointPathPrefix(t, result, "enter_bind", "socket:1:")
assertTracepointPathPrefix(t, result, "enter_connect", "socket:1:")
@@ -76,12 +81,12 @@ func TestSocketAcceptLifecyclePlain(t *testing.T) {
}
func TestSocketIntrospection(t *testing.T) {
- result, _ := runScenarioResult(t, "socket-introspection", []ExpectedEvent{
+ result, _ := runScenarioResultWithIorArgs(t, "socket-introspection", []ExpectedEvent{
{Tracepoint: "enter_getsockname", MinCount: 1},
{Tracepoint: "enter_getpeername", MinCount: 1},
{Tracepoint: "enter_setsockopt", MinCount: 1},
{Tracepoint: "enter_getsockopt", MinCount: 1},
- })
+ }, socketTraceArgs)
assertTracepointPathPrefix(t, result, "enter_getsockname", "socket:1:")
assertTracepointPathPrefix(t, result, "enter_getpeername", "socket:1:")