github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/lockfile/lockfile_test.go (about)

     1  // Copyright 2018 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package lockfile
     6  
     7  import (
     8  	"io/ioutil"
     9  	"os"
    10  	"os/exec"
    11  	"path/filepath"
    12  	"testing"
    13  )
    14  
    15  func testProcess(t *testing.T) *os.Process {
    16  	p := exec.Command("sleep", "1000")
    17  	if err := p.Start(); err != nil {
    18  		t.Fatal(err)
    19  	}
    20  
    21  	go p.Wait()
    22  	return p.Process
    23  }
    24  
    25  func TestTryLock(t *testing.T) {
    26  	p1 := testProcess(t)
    27  	defer p1.Kill()
    28  	p2 := testProcess(t)
    29  	defer p2.Kill()
    30  
    31  	dir, err := ioutil.TempDir("", "lockfile-")
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  	defer os.RemoveAll(dir)
    36  
    37  	l := &Lockfile{
    38  		path: filepath.Join(dir, "test1"),
    39  		pid:  p1.Pid,
    40  	}
    41  	if err := l.TryLock(); err != nil {
    42  		t.Fatalf("l(%d).TryLock() = %v, want nil", l.pid, err)
    43  	}
    44  
    45  	l2 := &Lockfile{
    46  		path: l.path,
    47  		pid:  p2.Pid,
    48  	}
    49  	if err := l2.TryLock(); err != ErrBusy {
    50  		t.Fatalf("l(%d).TryLock() = %v, want ErrBusy", l2.pid, err)
    51  	}
    52  
    53  	if err := l.Unlock(); err != nil {
    54  		t.Fatal(err)
    55  	}
    56  
    57  	if err := l.Unlock(); err != ErrRogueDeletion {
    58  		t.Fatalf("2nd Unlock() = %v, want ErrRogueDeletion", err)
    59  	}
    60  
    61  	if err := l2.TryLock(); err != nil {
    62  		t.Fatalf("l(%d).TryLock() = %v, want nil", l2.pid, err)
    63  	}
    64  }
    65  
    66  func TestLockFileRemoval(t *testing.T) {
    67  	p := testProcess(t)
    68  	defer p.Kill()
    69  
    70  	dir, err := ioutil.TempDir("", "lockfile-")
    71  	if err != nil {
    72  		t.Fatal(err)
    73  	}
    74  	defer os.RemoveAll(dir)
    75  
    76  	l := &Lockfile{
    77  		path: filepath.Join(dir, "test2"),
    78  		pid:  p.Pid,
    79  	}
    80  	if err := l.TryLock(); err != nil {
    81  		t.Fatalf("l(%d).TryLock() = %v, want nil", l.pid, err)
    82  	}
    83  
    84  	// Evil actor deletes the lockfile.
    85  	if err := os.Remove(l.path); err != nil {
    86  		t.Fatalf("remove(%v) = %v, want nil", l.path, err)
    87  	}
    88  
    89  	if err := l.Unlock(); err != ErrRogueDeletion {
    90  		t.Fatalf("l(%d).Unlock() = %v, want ErrRogueDeletion", l.pid, err)
    91  	}
    92  
    93  	if err := l.TryLock(); err != nil {
    94  		t.Fatalf("l(%d).TryLock() = %v, want nil", l.pid, err)
    95  	}
    96  }
    97  
    98  func TestDeadProcess(t *testing.T) {
    99  	p1 := testProcess(t)
   100  	defer p1.Kill()
   101  	p2 := testProcess(t)
   102  	defer p2.Kill()
   103  
   104  	dir, err := ioutil.TempDir("", "lockfile-")
   105  	if err != nil {
   106  		t.Fatal(err)
   107  	}
   108  	defer os.RemoveAll(dir)
   109  
   110  	l := &Lockfile{
   111  		path: filepath.Join(dir, "test3"),
   112  		pid:  p1.Pid,
   113  	}
   114  	if err := l.TryLock(); err != nil {
   115  		t.Fatalf("l(%d).TryLock() = %v, want nil", l.pid, err)
   116  	}
   117  	if err := p1.Kill(); err != nil {
   118  		t.Fatalf("Kill() = %v, want nil", err)
   119  	}
   120  	p1.Wait()
   121  
   122  	l2 := &Lockfile{
   123  		path: l.path,
   124  		pid:  p2.Pid,
   125  	}
   126  	if err := l2.TryLock(); err != nil {
   127  		t.Fatalf("l(%d).TryLock() = %v, want nil", l2.pid, err)
   128  	}
   129  	if err := l2.Unlock(); err != nil {
   130  		t.Fatalf("l(%d).Unlock() = %v, want nil", l2.pid, err)
   131  	}
   132  }