File: file_lock_test.go

package info (click to toggle)
golang-github-golang-leveldb 0.0~git20161231.0.3435554-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 1,004 kB
  • sloc: cpp: 166; makefile: 11
file content (79 lines) | stat: -rw-r--r-- 2,111 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// Copyright 2014 The LevelDB-Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package db_test

import (
	"bytes"
	"flag"
	"io/ioutil"
	"os"
	"os/exec"
	"testing"

	"github.com/golang/leveldb/db"
)

var lockFilename = flag.String("lockfile", "", "File to lock. A non-empty value implies a child process.")

func spawn(prog, filename string) ([]byte, error) {
	return exec.Command(prog, "-lockfile", filename, "-test.v",
		"-test.run=TestLock$").CombinedOutput()
}

// TestLock locks a file, spawns a second process that attempts to grab the
// lock to verify it fails.
// Then it closes the lock, and spawns a third copy to verify it can be
// relocked.
func TestLock(t *testing.T) {
	child := *lockFilename != ""
	var filename string
	if child {
		filename = *lockFilename
	} else {
		f, err := ioutil.TempFile("", "golang-leveldb-db-testlock-")
		if err != nil {
			t.Fatal(err)
		}
		filename = f.Name()
		defer os.Remove(filename)
	}

	// Avoid truncating an existing, non-empty file.
	fi, err := os.Stat(filename)
	if err == nil && fi.Size() != 0 {
		t.Fatalf("The file %s is not empty", filename)
	}

	t.Logf("Locking %s\n", filename)
	lock, err := db.DefaultFileSystem.Lock(filename)
	if err != nil {
		t.Fatalf("Could not lock %s: %v", filename, err)
	}

	if !child {
		t.Logf("Spawning child, should fail to grab lock.")
		out, err := spawn(os.Args[0], filename)
		if err == nil {
			t.Fatalf("Attempt to grab open lock should have failed.\n%s", out)
		}
		if !bytes.Contains(out, []byte("Could not lock")) {
			t.Fatalf("Child failed with unexpected output: %s\n", out)
		}
		t.Logf("Child failed to grab lock as expected.")
	}

	t.Logf("Unlocking %s", filename)
	if err := lock.Close(); err != nil {
		t.Fatalf("Could not unlock %s: %v", filename, err)
	}

	if !child {
		t.Logf("Spawning child, should successfully grab lock.")
		if out, err := spawn(os.Args[0], filename); err != nil {
			t.Fatalf("Attempt to re-open lock should have succeeded: %v\n%s",
				err, out)
		}
		t.Logf("Child grabbed lock.")
	}
}