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  }