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