github.com/sagernet/netlink@v0.0.0-20240612041022-b9a21c07ac6a/proc_event_test.go (about)

     1  //go:build linux
     2  // +build linux
     3  
     4  package netlink
     5  
     6  import (
     7  	"os"
     8  	"os/exec"
     9  	"runtime"
    10  	"testing"
    11  
    12  	"github.com/vishvananda/netns"
    13  )
    14  
    15  func TestSubscribeProcEvent(t *testing.T) {
    16  	skipUnlessRoot(t)
    17  	runtime.LockOSThread()
    18  	defer runtime.UnlockOSThread()
    19  
    20  	pid1ns, err := netns.GetFromPid(1)
    21  	if err != nil {
    22  		panic(err)
    23  	}
    24  
    25  	err = netns.Set(pid1ns)
    26  	if err != nil {
    27  		panic(err)
    28  	}
    29  
    30  	ch := make(chan ProcEvent)
    31  	done := make(chan struct{})
    32  	defer close(done)
    33  
    34  	errChan := make(chan error)
    35  
    36  	if err := ProcEventMonitor(ch, done, errChan); err != nil {
    37  		t.Fatal(err)
    38  	}
    39  
    40  	cmd := exec.Command("false")
    41  	if err := cmd.Start(); err != nil {
    42  		t.Fatal(err)
    43  	}
    44  
    45  	// first we wait for proc - i.e. childTgid is cmd.Process.Pid
    46  	for {
    47  		e := <-ch
    48  		t.Logf("pid: %+v e: %+v", os.Getpid(), e)
    49  		if e.Msg.Tgid() == uint32(os.Getpid()) {
    50  			if forkEvent, ok := e.Msg.(*ForkProcEvent); ok {
    51  				if forkEvent.ChildTgid == uint32(cmd.Process.Pid) {
    52  					break
    53  				}
    54  			}
    55  		}
    56  	}
    57  
    58  	// wait for exec event
    59  	for {
    60  		e := <-ch
    61  		if e.Msg.Tgid() == uint32(cmd.Process.Pid) {
    62  			if _, ok := e.Msg.(*ExecProcEvent); ok {
    63  				break
    64  			}
    65  		}
    66  	}
    67  
    68  	cmd.Wait()
    69  	for {
    70  		e := <-ch
    71  		if e.Msg.Tgid() == uint32(cmd.Process.Pid) {
    72  			if exitEvent, ok := e.Msg.(*ExitProcEvent); ok {
    73  				if exitEvent.ExitCode != 256 {
    74  					t.Errorf("Expected error code 256 (-1), but got %+v", exitEvent)
    75  				}
    76  				break
    77  			}
    78  		}
    79  	}
    80  
    81  	done <- struct{}{}
    82  }