github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/chunks/remote_requests_test.go (about) 1 // Copyright 2019 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // This file incorporates work covered by the following copyright and 16 // permission notice: 17 // 18 // Copyright 2016 Attic Labs, Inc. All rights reserved. 19 // Licensed under the Apache License, version 2.0: 20 // http://www.apache.org/licenses/LICENSE-2.0 21 22 package chunks 23 24 import ( 25 "sync" 26 "testing" 27 28 "github.com/stretchr/testify/assert" 29 30 "github.com/dolthub/dolt/go/store/hash" 31 ) 32 33 func TestGetRequestBatch(t *testing.T) { 34 assert := assert.New(t) 35 h0 := hash.Parse("00000000000000000000000000000000") 36 c1 := NewChunk([]byte("abc")) 37 h1 := c1.Hash() 38 c2 := NewChunk([]byte("123")) 39 h2 := c2.Hash() 40 41 tally := func(b bool, trueCnt, falseCnt *int) { 42 if b { 43 *trueCnt++ 44 } else { 45 *falseCnt++ 46 } 47 } 48 49 req0chan := make(chan bool, 1) 50 req1chan := make(chan *Chunk, 1) 51 req2chan := make(chan bool, 1) 52 req3chan := make(chan bool, 1) 53 req4chan := make(chan *Chunk, 1) 54 defer func() { close(req0chan); close(req1chan); close(req2chan); close(req3chan); close(req4chan) }() 55 56 batch := ReadBatch{ 57 h0: []OutstandingRequest{OutstandingAbsent(req0chan), OutstandingGet(req1chan)}, 58 h1: []OutstandingRequest{OutstandingAbsent(req2chan)}, 59 h2: []OutstandingRequest{OutstandingAbsent(req3chan), OutstandingGet(req4chan)}, 60 } 61 go func() { 62 for requestedHash, reqs := range batch { 63 for _, req := range reqs { 64 if requestedHash == h1 { 65 req.Satisfy(h1, &c1) 66 delete(batch, h1) 67 } else if requestedHash == h2 { 68 req.Satisfy(h2, &c2) 69 delete(batch, h2) 70 } 71 } 72 } 73 batch.Close() 74 }() 75 76 var r0True, r0False, r2True, r2False, r3True, r3False int 77 b := <-req0chan 78 tally(b, &r0True, &r0False) 79 c := <-req1chan 80 assert.EqualValues(EmptyChunk.Hash(), c.Hash()) 81 b = <-req2chan 82 tally(b, &r2True, &r2False) 83 b = <-req3chan 84 tally(b, &r3True, &r3False) 85 c = <-req4chan 86 assert.EqualValues(c2.Hash(), c.Hash()) 87 88 assert.Equal(1, r0True) 89 assert.Equal(0, r0False) 90 assert.Equal(0, r2True) 91 assert.Equal(1, r2False) 92 assert.Equal(0, r3True) 93 assert.Equal(1, r3False) 94 } 95 96 func TestGetManyRequestBatch(t *testing.T) { 97 assert := assert.New(t) 98 h0 := hash.Parse("00000000000000000000000000000000") 99 c1 := NewChunk([]byte("abc")) 100 h1 := c1.Hash() 101 c2 := NewChunk([]byte("123")) 102 h2 := c2.Hash() 103 104 chunks := make(chan *Chunk) 105 hashes := hash.NewHashSet(h0, h1, h2) 106 wg := &sync.WaitGroup{} 107 wg.Add(len(hashes)) 108 go func() { wg.Wait(); close(chunks) }() 109 110 req := NewGetManyRequest(hashes, wg, chunks) 111 batch := ReadBatch{ 112 h0: {req.Outstanding()}, 113 h1: {req.Outstanding()}, 114 h2: {req.Outstanding()}, 115 } 116 go func() { 117 for reqHash, reqs := range batch { 118 for _, req := range reqs { 119 if reqHash == h1 { 120 req.Satisfy(h1, &c1) 121 delete(batch, h1) 122 } else if reqHash == h2 { 123 req.Satisfy(h2, &c2) 124 delete(batch, h2) 125 } 126 } 127 } 128 batch.Close() 129 }() 130 131 for c := range chunks { 132 hashes.Remove(c.Hash()) 133 } 134 assert.Len(hashes, 1) 135 assert.True(hashes.Has(h0)) 136 } 137 138 func TestAbsentManyRequestBatch(t *testing.T) { 139 assert := assert.New(t) 140 h0 := hash.Parse("00000000000000000000000000000000") 141 c1 := NewChunk([]byte("abc")) 142 h1 := c1.Hash() 143 c2 := NewChunk([]byte("123")) 144 h2 := c2.Hash() 145 146 found := make(chan hash.Hash) 147 hashes := hash.NewHashSet(h0, h1, h2) 148 wg := &sync.WaitGroup{} 149 wg.Add(len(hashes)) 150 go func() { wg.Wait(); close(found) }() 151 152 req := NewAbsentManyRequest(hashes, wg, found) 153 batch := ReadBatch{} 154 for h := range req.Hashes() { 155 batch[h] = []OutstandingRequest{req.Outstanding()} 156 } 157 go func() { 158 for reqHash, reqs := range batch { 159 for _, req := range reqs { 160 if reqHash == h1 { 161 req.Satisfy(h1, &EmptyChunk) 162 delete(batch, h1) 163 } else if reqHash == h2 { 164 req.Satisfy(h2, &EmptyChunk) 165 delete(batch, h2) 166 } 167 } 168 } 169 batch.Close() 170 }() 171 172 for h := range found { 173 hashes.Remove(h) 174 } 175 assert.Len(hashes, 1) 176 assert.True(hashes.Has(h0)) 177 }