pidfile_test.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package pidfile // import "github.com/docker/docker/pkg/pidfile"
  2. import (
  3. "errors"
  4. "os"
  5. "os/exec"
  6. "path/filepath"
  7. "runtime"
  8. "strconv"
  9. "testing"
  10. )
  11. func TestWrite(t *testing.T) {
  12. path := filepath.Join(t.TempDir(), "testfile")
  13. err := Write(path, 0)
  14. if err == nil {
  15. t.Fatal("writing PID < 1 should fail")
  16. }
  17. err = Write(path, os.Getpid())
  18. if err != nil {
  19. t.Fatal("Could not create test file", err)
  20. }
  21. err = Write(path, os.Getpid())
  22. if err == nil {
  23. t.Error("Test file creation not blocked")
  24. }
  25. pid, err := Read(path)
  26. if err != nil {
  27. t.Error(err)
  28. }
  29. if pid != os.Getpid() {
  30. t.Errorf("expected pid %d, got %d", os.Getpid(), pid)
  31. }
  32. }
  33. func TestRead(t *testing.T) {
  34. tmpDir := t.TempDir()
  35. t.Run("non-existing pidFile", func(t *testing.T) {
  36. _, err := Read(filepath.Join(tmpDir, "nosuchfile"))
  37. if !errors.Is(err, os.ErrNotExist) {
  38. t.Errorf("expected an os.ErrNotExist, got: %+v", err)
  39. }
  40. })
  41. // Verify that we ignore a malformed PID in the file.
  42. t.Run("malformed pid", func(t *testing.T) {
  43. // Not using Write here, to test Read in isolation.
  44. pidFile := filepath.Join(tmpDir, "pidfile-malformed")
  45. err := os.WriteFile(pidFile, []byte("something that's not an integer"), 0o644)
  46. if err != nil {
  47. t.Fatal(err)
  48. }
  49. pid, err := Read(pidFile)
  50. if err != nil {
  51. t.Error(err)
  52. }
  53. if pid != 0 {
  54. t.Errorf("expected pid %d, got %d", 0, pid)
  55. }
  56. })
  57. t.Run("zero pid", func(t *testing.T) {
  58. // Not using Write here, to test Read in isolation.
  59. pidFile := filepath.Join(tmpDir, "pidfile-zero")
  60. err := os.WriteFile(pidFile, []byte(strconv.Itoa(0)), 0o644)
  61. if err != nil {
  62. t.Fatal(err)
  63. }
  64. pid, err := Read(pidFile)
  65. if err != nil {
  66. t.Error(err)
  67. }
  68. if pid != 0 {
  69. t.Errorf("expected pid %d, got %d", 0, pid)
  70. }
  71. })
  72. t.Run("negative pid", func(t *testing.T) {
  73. // Not using Write here, to test Read in isolation.
  74. pidFile := filepath.Join(tmpDir, "pidfile-negative")
  75. err := os.WriteFile(pidFile, []byte(strconv.Itoa(-1)), 0o644)
  76. if err != nil {
  77. t.Fatal(err)
  78. }
  79. pid, err := Read(pidFile)
  80. if err != nil {
  81. t.Error(err)
  82. }
  83. if pid != 0 {
  84. t.Errorf("expected pid %d, got %d", 0, pid)
  85. }
  86. })
  87. t.Run("current process pid", func(t *testing.T) {
  88. // Not using Write here, to test Read in isolation.
  89. pidFile := filepath.Join(tmpDir, "pidfile")
  90. err := os.WriteFile(pidFile, []byte(strconv.Itoa(os.Getpid())), 0o644)
  91. if err != nil {
  92. t.Fatal(err)
  93. }
  94. pid, err := Read(pidFile)
  95. if err != nil {
  96. t.Error(err)
  97. }
  98. if pid != os.Getpid() {
  99. t.Errorf("expected pid %d, got %d", os.Getpid(), pid)
  100. }
  101. })
  102. // Verify that we don't return a PID if the process exited.
  103. t.Run("exited process", func(t *testing.T) {
  104. if runtime.GOOS == "windows" {
  105. t.Skip("TODO: make this work on Windows")
  106. }
  107. // Get a PID of an exited process.
  108. cmd := exec.Command("echo", "hello world")
  109. err := cmd.Run()
  110. if err != nil {
  111. t.Fatal(err)
  112. }
  113. exitedPID := cmd.ProcessState.Pid()
  114. // Not using Write here, to test Read in isolation.
  115. pidFile := filepath.Join(tmpDir, "pidfile-exited")
  116. err = os.WriteFile(pidFile, []byte(strconv.Itoa(exitedPID)), 0o644)
  117. if err != nil {
  118. t.Fatal(err)
  119. }
  120. pid, err := Read(pidFile)
  121. if err != nil {
  122. t.Error(err)
  123. }
  124. if pid != 0 {
  125. t.Errorf("expected pid %d, got %d", 0, pid)
  126. }
  127. })
  128. }