github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/dbnode/client/session_fetch_metadata_test.go (about) 1 // Copyright (c) 2016 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package client 22 23 import ( 24 "errors" 25 "testing" 26 "time" 27 28 "github.com/m3db/m3/src/dbnode/storage/block" 29 "github.com/m3db/m3/src/dbnode/topology" 30 "github.com/m3db/m3/src/x/checked" 31 "github.com/m3db/m3/src/x/ident" 32 xtime "github.com/m3db/m3/src/x/time" 33 34 "github.com/stretchr/testify/assert" 35 "github.com/stretchr/testify/require" 36 ) 37 38 type testHostBlock struct { 39 host topology.Host 40 block block.Metadata 41 } 42 43 func TestPeerBlockMetadataIter(t *testing.T) { 44 var ( 45 inputCh = make(chan receivedBlockMetadata) 46 errCh = make(chan error, 1) 47 err = errors.New("foo") 48 ) 49 50 opts := newHostQueueTestOptions() 51 peer := newTestHostQueue(opts) 52 now := xtime.Now() 53 checksums := []uint32{1, 2, 3} 54 lastRead := now.Add(-100 * time.Millisecond) 55 inputs := []receivedBlockMetadata{ 56 { 57 peer: peer, 58 id: ident.StringID("foo"), 59 encodedTags: mustEncodeTags(t, ident.NewTags(ident.StringTag("aaa", "bbb"))), 60 block: blockMetadata{ 61 start: now, size: int64(1), checksum: &checksums[0], 62 }, 63 }, 64 { 65 peer: peer, 66 id: ident.StringID("foo"), 67 encodedTags: mustEncodeTags(t, ident.NewTags(ident.StringTag("aaa", "bbb"))), 68 block: blockMetadata{ 69 start: now.Add(time.Second), size: int64(2), checksum: &checksums[1], lastRead: lastRead, 70 }, 71 }, 72 { 73 peer: peer, 74 id: ident.StringID("bar"), 75 encodedTags: mustEncodeTags(t, ident.NewTags(ident.StringTag("ccc", "ddd"))), 76 block: blockMetadata{ 77 start: now, size: int64(3), checksum: &checksums[2], lastRead: lastRead, 78 }, 79 }, 80 { 81 peer: peer, 82 id: ident.StringID("baz"), 83 encodedTags: mustEncodeTags(t, ident.NewTags(ident.StringTag("eee", "fff"))), 84 block: blockMetadata{ 85 start: now, size: int64(4), checksum: nil, lastRead: lastRead, 86 }, 87 }, 88 } 89 90 go func() { 91 for _, input := range inputs { 92 inputCh <- input 93 } 94 errCh <- err 95 close(inputCh) 96 }() 97 98 var actual []testHostBlock 99 it := newMetadataIter(inputCh, errCh, 100 testTagDecodingPool, testIDPool) 101 for it.Next() { 102 host, curr := it.Current() 103 result := block.NewMetadata(curr.ID, curr.Tags, curr.Start, curr.Size, 104 curr.Checksum, curr.LastRead) 105 actual = append(actual, testHostBlock{host, result}) 106 } 107 108 expected := []testHostBlock{ 109 {h, block.NewMetadata(ident.StringID("foo"), 110 ident.NewTags(ident.StringTag("aaa", "bbb")), 111 inputs[0].block.start, inputs[0].block.size, 112 inputs[0].block.checksum, inputs[0].block.lastRead)}, 113 {h, block.NewMetadata(ident.StringID("foo"), 114 ident.NewTags(ident.StringTag("aaa", "bbb")), 115 inputs[1].block.start, inputs[1].block.size, 116 inputs[1].block.checksum, inputs[1].block.lastRead)}, 117 {h, block.NewMetadata(ident.StringID("bar"), 118 ident.NewTags(ident.StringTag("ccc", "ddd")), 119 inputs[2].block.start, inputs[2].block.size, 120 inputs[2].block.checksum, inputs[2].block.lastRead)}, 121 {h, block.NewMetadata(ident.StringID("baz"), 122 ident.NewTags(ident.StringTag("eee", "fff")), 123 inputs[3].block.start, inputs[3].block.size, 124 inputs[3].block.checksum, inputs[3].block.lastRead)}, 125 } 126 127 require.Equal(t, len(expected), len(actual)) 128 for i, expected := range expected { 129 actual := actual[i] 130 assert.Equal(t, expected.host.String(), actual.host.String()) 131 assert.True(t, expected.block.ID.Equal(actual.block.ID)) 132 tagMatcher := ident.NewTagIterMatcher(ident.NewTagsIterator(expected.block.Tags)) 133 assert.True(t, tagMatcher.Matches(ident.NewTagsIterator(actual.block.Tags))) 134 assert.True(t, expected.block.Start.Equal(actual.block.Start)) 135 assert.Equal(t, expected.block.Size, actual.block.Size) 136 assert.Equal(t, expected.block.Checksum, actual.block.Checksum) 137 assert.True(t, expected.block.LastRead.Equal(actual.block.LastRead)) 138 } 139 } 140 141 func mustEncodeTags(t *testing.T, tags ident.Tags) checked.Bytes { 142 encoder := testTagEncodingPool.Get() 143 err := encoder.Encode(ident.NewTagsIterator(tags)) 144 require.NoError(t, err) 145 data, ok := encoder.Data() 146 require.True(t, ok) 147 return data 148 }