diff options
author | Andrew G. Morgan <morgan@kernel.org> | 2023-02-06 18:55:40 -0800 |
---|---|---|
committer | Andrew G. Morgan <morgan@kernel.org> | 2023-02-06 18:55:40 -0800 |
commit | b6d210ee03405f05152542807ee71b1e9c87fe60 (patch) | |
tree | 740b1d20949dfcffb1332d073c82cba1201936c0 | |
parent | 27954dde34fcb8c306fa4d80fdbb5950f0949e03 (diff) | |
download | libcap-b6d210ee03405f05152542807ee71b1e9c87fe60.tar.gz |
Add some more explicit testing to the psx_test.go code.
While we test this in many other places, we didn't test this
explicitly in the psx.go local testing before. Now we do.
Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r-- | psx/psx_test.go | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/psx/psx_test.go b/psx/psx_test.go index 4b90f63..922e7e4 100644 --- a/psx/psx_test.go +++ b/psx/psx_test.go @@ -2,6 +2,7 @@ package psx import ( "runtime" + "sync" "syscall" "testing" ) @@ -41,9 +42,65 @@ func killAThread(c <-chan struct{}) { <-c } +// Test state is mirrored as expected. +func TestShared(t *testing.T) { + const prGetKeepCaps = 7 + const prSetKeepCaps = 8 + + var wg sync.WaitGroup + + newTracker := func() chan<- uintptr { + ch := make(chan uintptr) + go func() { + runtime.LockOSThread() + defer wg.Done() + tid := syscall.Gettid() + for { + if _, ok := <-ch; !ok { + break + } + val, ok := <-ch + if !ok { + break + } + got, _, e := Syscall3(syscall.SYS_PRCTL, prGetKeepCaps, val, 0) + if e != 0 { + t.Fatalf("[%d] psx:prctl(SET_KEEPCAPS, %d) failed: %v", tid, val, syscall.Errno(e)) + } + if got != val { + t.Errorf("bad keepcaps value [%d]: got=%d, want=%d", tid, got, val) + } + if _, ok := <-ch; !ok { + break + } + } + }() + return ch + } + + var tracked []chan<- uintptr + for i := 0; i <= 10; i++ { + val := uintptr(i & 1) + if _, _, e := Syscall3(syscall.SYS_PRCTL, prSetKeepCaps, val, 0); e != 0 { + t.Fatalf("[%d] psx:prctl(SET_KEEPCAPS, %d) failed: %v", i, i&1, syscall.Errno(e)) + } + wg.Add(1) + tracked = append(tracked, newTracker()) + for _, ch := range tracked { + ch <- 2 // start serialization. + ch <- val // definitely written after change. + ch <- 3 // end serialization. + } + } + for _, ch := range tracked { + close(ch) + } + wg.Wait() +} + // Test to confirm no regression against: // -// https://github.com/golang/go/issues/42494 +// https://github.com/golang/go/issues/42494 func TestThreadChurn(t *testing.T) { const prSetKeepCaps = 8 |