github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/vfs/file_lock_test.go (about) 1 // Copyright 2014 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package vfs_test 6 7 import ( 8 "bytes" 9 "flag" 10 "io/ioutil" 11 "os" 12 "os/exec" 13 "testing" 14 15 "github.com/petermattis/pebble/vfs" 16 ) 17 18 var lockFilename = flag.String("lockfile", "", "File to lock. A non-empty value implies a child process.") 19 20 func spawn(prog, filename string) ([]byte, error) { 21 return exec.Command(prog, "-lockfile", filename, "-test.v", 22 "-test.run=TestLock$").CombinedOutput() 23 } 24 25 // TestLock locks a file, spawns a second process that attempts to grab the 26 // lock to verify it fails. 27 // Then it closes the lock, and spawns a third copy to verify it can be 28 // relocked. 29 func TestLock(t *testing.T) { 30 child := *lockFilename != "" 31 var filename string 32 if child { 33 filename = *lockFilename 34 } else { 35 f, err := ioutil.TempFile("", "golang-pebble-db-testlock-") 36 if err != nil { 37 t.Fatal(err) 38 } 39 filename = f.Name() 40 defer os.Remove(filename) 41 } 42 43 // Avoid truncating an existing, non-empty file. 44 fi, err := os.Stat(filename) 45 if err == nil && fi.Size() != 0 { 46 t.Fatalf("The file %s is not empty", filename) 47 } 48 49 t.Logf("Locking %s\n", filename) 50 lock, err := vfs.Default.Lock(filename) 51 if err != nil { 52 t.Fatalf("Could not lock %s: %v", filename, err) 53 } 54 55 if !child { 56 t.Logf("Spawning child, should fail to grab lock.") 57 out, err := spawn(os.Args[0], filename) 58 if err == nil { 59 t.Fatalf("Attempt to grab open lock should have failed.\n%s", out) 60 } 61 if !bytes.Contains(out, []byte("Could not lock")) { 62 t.Fatalf("Child failed with unexpected output: %s\n", out) 63 } 64 t.Logf("Child failed to grab lock as expected.") 65 } 66 67 t.Logf("Unlocking %s", filename) 68 if err := lock.Close(); err != nil { 69 t.Fatalf("Could not unlock %s: %v", filename, err) 70 } 71 72 if !child { 73 t.Logf("Spawning child, should successfully grab lock.") 74 if out, err := spawn(os.Args[0], filename); err != nil { 75 t.Fatalf("Attempt to re-open lock should have succeeded: %v\n%s", 76 err, out) 77 } 78 t.Logf("Child grabbed lock.") 79 } 80 }