Files
docker-cli/components/engine/pkg/locker/locker_test.go
T
Brian Goff 365046209e Fix potential races in the volume store
Uses finer grained locking so that each volume name gets its own lock
rather than only being protected by the global lock, which itself needs
to be unlocked during cetain operations (`create` especially`)

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: fe66fdd18c0307cc02e6aeff8625c179452b8436
Component: engine
2015-11-04 16:59:47 -05:00

91 lines
1.3 KiB
Go

package locker
import (
"runtime"
"testing"
)
func TestLockCounter(t *testing.T) {
l := &lockCtr{}
l.inc()
if l.waiters != 1 {
t.Fatal("counter inc failed")
}
l.dec()
if l.waiters != 0 {
t.Fatal("counter dec failed")
}
}
func TestLockerLock(t *testing.T) {
l := New()
l.Lock("test")
ctr := l.locks["test"]
if ctr.count() != 0 {
t.Fatalf("expected waiters to be 0, got :%d", ctr.waiters)
}
chDone := make(chan struct{})
go func() {
l.Lock("test")
close(chDone)
}()
runtime.Gosched()
select {
case <-chDone:
t.Fatal("lock should not have returned while it was still held")
default:
}
if ctr.count() != 1 {
t.Fatalf("expected waiters to be 1, got: %d", ctr.count())
}
if err := l.Unlock("test"); err != nil {
t.Fatal(err)
}
runtime.Gosched()
select {
case <-chDone:
default:
// one more time just to be sure
runtime.Gosched()
select {
case <-chDone:
default:
t.Fatalf("lock should have completed")
}
}
if ctr.count() != 0 {
t.Fatalf("expected waiters to be 0, got: %d", ctr.count())
}
}
func TestLockerUnlock(t *testing.T) {
l := New()
l.Lock("test")
l.Unlock("test")
chDone := make(chan struct{})
go func() {
l.Lock("test")
close(chDone)
}()
runtime.Gosched()
select {
case <-chDone:
default:
t.Fatalf("lock should not be blocked")
}
}