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  }