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 }