1 // Copyright 2018 The Go 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.
5 // js does not support inter-process file locking.
8 package lockedfile_test
17 "cmd/go/internal/lockedfile"
20 func mustTempDir(t *testing.T) (dir string, remove func()) {
23 dir, err := ioutil.TempDir("", filepath.Base(t.Name()))
27 return dir, func() { os.RemoveAll(dir) }
31 quiescent = 10 * time.Millisecond
32 probablyStillBlocked = 10 * time.Second
35 func mustBlock(t *testing.T, desc string, f func()) (wait func(*testing.T)) {
38 done := make(chan struct{})
46 t.Fatalf("%s unexpectedly did not block", desc)
49 case <-time.After(quiescent):
50 return func(t *testing.T) {
53 case <-time.After(probablyStillBlocked):
54 t.Fatalf("%s is unexpectedly still blocked after %v", desc, probablyStillBlocked)
61 func TestMutexExcludes(t *testing.T) {
64 dir, remove := mustTempDir(t)
67 path := filepath.Join(dir, "lock")
69 mu := lockedfile.MutexAt(path)
70 t.Logf("mu := MutexAt(_)")
72 unlock, err := mu.Lock()
74 t.Fatalf("mu.Lock: %v", err)
76 t.Logf("unlock, _ := mu.Lock()")
78 mu2 := lockedfile.MutexAt(mu.Path)
79 t.Logf("mu2 := MutexAt(mu.Path)")
81 wait := mustBlock(t, "mu2.Lock()", func() {
82 unlock2, err := mu2.Lock()
84 t.Errorf("mu2.Lock: %v", err)
87 t.Logf("unlock2, _ := mu2.Lock()")
97 func TestReadWaitsForLock(t *testing.T) {
100 dir, remove := mustTempDir(t)
103 path := filepath.Join(dir, "timestamp.txt")
105 f, err := lockedfile.Create(path)
107 t.Fatalf("Create: %v", err)
115 _, err = f.WriteString(part1)
117 t.Fatalf("WriteString: %v", err)
119 t.Logf("WriteString(%q) = <nil>", part1)
121 wait := mustBlock(t, "Read", func() {
122 b, err := lockedfile.Read(path)
124 t.Errorf("Read: %v", err)
128 const want = part1 + part2
131 t.Logf("Read(_) = %q", got)
133 t.Errorf("Read(_) = %q, _; want %q", got, want)
137 _, err = f.WriteString(part2)
139 t.Errorf("WriteString: %v", err)
141 t.Logf("WriteString(%q) = <nil>", part2)
148 func TestCanLockExistingFile(t *testing.T) {
151 dir, remove := mustTempDir(t)
153 path := filepath.Join(dir, "existing.txt")
155 if err := ioutil.WriteFile(path, []byte("ok"), 0777); err != nil {
156 t.Fatalf("ioutil.WriteFile: %v", err)
159 f, err := lockedfile.Edit(path)
161 t.Fatalf("first Edit: %v", err)
164 wait := mustBlock(t, "Edit", func() {
165 other, err := lockedfile.Edit(path)
167 t.Errorf("second Edit: %v", err)