| // Copyright 2023 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package os_test |
| |
| import ( |
| "errors" |
| "internal/testenv" |
| "os" |
| "syscall" |
| "testing" |
| ) |
| |
| func TestFindProcessViaPidfd(t *testing.T) { |
| testenv.MustHaveGoBuild(t) |
| t.Parallel() |
| |
| if err := os.CheckPidfdOnce(); err != nil { |
| // Non-pidfd code paths tested in exec_unix_test.go. |
| t.Skipf("skipping: pidfd not available: %v", err) |
| } |
| |
| p, err := os.StartProcess(testenv.GoToolPath(t), []string{"go"}, &os.ProcAttr{}) |
| if err != nil { |
| t.Fatalf("starting test process: %v", err) |
| } |
| p.Wait() |
| |
| // Use pid of a non-existing process. |
| proc, err := os.FindProcess(p.Pid) |
| // FindProcess should never return errors on Unix. |
| if err != nil { |
| t.Fatalf("FindProcess: got error %v, want <nil>", err) |
| } |
| // FindProcess should never return nil Process. |
| if proc == nil { |
| t.Fatal("FindProcess: got nil, want non-nil") |
| } |
| if proc.Status() != os.StatusDone { |
| t.Fatalf("got process status: %v, want %d", proc.Status(), os.StatusDone) |
| } |
| |
| // Check that all Process' public methods work as expected with |
| // "done" Process. |
| if err := proc.Kill(); err != os.ErrProcessDone { |
| t.Errorf("Kill: got %v, want %v", err, os.ErrProcessDone) |
| } |
| if err := proc.Signal(os.Kill); err != os.ErrProcessDone { |
| t.Errorf("Signal: got %v, want %v", err, os.ErrProcessDone) |
| } |
| if _, err := proc.Wait(); !errors.Is(err, syscall.ECHILD) { |
| t.Errorf("Wait: got %v, want %v", err, os.ErrProcessDone) |
| } |
| // Release never returns errors on Unix. |
| if err := proc.Release(); err != nil { |
| t.Fatalf("Release: got %v, want <nil>", err) |
| } |
| } |