github.com/braveheart12/insolar-09-08-19@v0.8.7/ledger/storage/lock_test.go (about) 1 /* 2 * Copyright 2019 Insolar Technologies 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package storage 17 18 import ( 19 "fmt" 20 "strings" 21 "sync" 22 "testing" 23 "time" 24 25 "github.com/insolar/insolar/core" 26 "github.com/stretchr/testify/assert" 27 ) 28 29 func Test_IDLockTheSame(t *testing.T) { 30 tl := newtestlocker() 31 id1 := core.RecordID{0x0A} 32 id2 := core.RecordID{0x0A} 33 start1 := make(chan bool) 34 start2 := make(chan bool) 35 var wg sync.WaitGroup 36 wg.Add(2) 37 go func() { 38 <-start1 39 tl.Lock("lock1", &id1) 40 close(start2) 41 42 time.Sleep(time.Millisecond * 50) 43 tl.Unlock("unlock1", &id1) 44 wg.Done() 45 }() 46 go func() { 47 <-start2 48 tl.Lock("lock2", &id2) 49 tl.Unlock("unlock2", &id2) 50 wg.Done() 51 }() 52 close(start1) 53 wg.Wait() 54 55 expectsteps := []string{ 56 "before-lock1", 57 "before-lock2", 58 "before-unlock1", 59 "before-unlock2", 60 } 61 assert.Equal(t, expectsteps, tl.synclist.list, "steps in proper order") 62 } 63 64 func Test_IDLockDifferent(t *testing.T) { 65 tl := newtestlocker() 66 id1 := core.NewRecordID(0, []byte{0x0A}) 67 id2 := core.NewRecordID(1, []byte{0x0A}) 68 end := make(chan bool) 69 go func() { 70 tl.Lock("lock1", id1) 71 tl.Lock("lock2", id2) 72 tl.Unlock("unlock1", id1) 73 tl.Unlock("unlock2", id2) 74 close(end) 75 }() 76 select { 77 case <-end: 78 case <-time.After(500 * time.Millisecond): 79 t.Fatal("Got deadlock. Different record.ID should not lock each other.") 80 } 81 82 expectsteps := []string{ 83 "before-lock1", 84 "before-lock2", 85 "before-unlock1", 86 "before-unlock2", 87 } 88 assert.Equal(t, expectsteps, tl.synclist.list, "steps in proper order") 89 } 90 91 // test helpers 92 93 type synclist struct { 94 sync.Mutex 95 list []string 96 } 97 98 type testlock struct { 99 lock *IDLocker 100 synclist *synclist 101 } 102 103 func newtestlocker() *testlock { 104 return &testlock{ 105 lock: NewIDLocker(), 106 synclist: &synclist{list: []string{}}, 107 } 108 } 109 110 func (l *synclist) Add(name string) { 111 l.Lock() 112 l.list = append(l.list, name) 113 l.Unlock() 114 } 115 116 func (l *synclist) String() string { 117 s := []string{"Steps:"} 118 for n, step := range l.list { 119 s = append(s, fmt.Sprintf(" %v: %v", n, step)) 120 } 121 return strings.Join(s, "\n") 122 } 123 124 func (tl *testlock) Lock(name string, id *core.RecordID) { 125 tl.synclist.Add("before-" + name) 126 tl.lock.Lock(id) 127 } 128 129 func (tl *testlock) Unlock(name string, id *core.RecordID) { 130 tl.synclist.Add("before-" + name) 131 tl.lock.Unlock(id) 132 }