github.com/m3db/m3@v1.5.0/src/dbnode/integration/integration_index_verify.go (about)

     1  // Copyright (c) 2018 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 integration
    22  
    23  import (
    24  	"fmt"
    25  	"testing"
    26  
    27  	"github.com/m3db/m3/src/dbnode/client"
    28  	"github.com/m3db/m3/src/dbnode/integration/generate"
    29  	"github.com/m3db/m3/src/x/ident"
    30  
    31  	"github.com/stretchr/testify/assert"
    32  	"github.com/stretchr/testify/require"
    33  )
    34  
    35  type verifyQueryMetadataResultsOptions struct {
    36  	namespace  ident.ID
    37  	exhaustive bool
    38  	expected   []generate.Series
    39  }
    40  
    41  type verifyQueryMetadataResult struct {
    42  	series  generate.Series
    43  	matched bool
    44  }
    45  
    46  func verifyQueryMetadataResults(
    47  	t *testing.T,
    48  	iter client.TaggedIDsIterator,
    49  	exhaustive bool,
    50  	opts verifyQueryMetadataResultsOptions,
    51  ) {
    52  	assert.Equal(t, opts.exhaustive, exhaustive)
    53  
    54  	expected := make(map[string]*verifyQueryMetadataResult, len(opts.expected))
    55  	for _, series := range opts.expected {
    56  		expected[series.ID.String()] = &verifyQueryMetadataResult{
    57  			series:  series,
    58  			matched: false,
    59  		}
    60  	}
    61  
    62  	compared := 0
    63  	for iter.Next() {
    64  		compared++
    65  
    66  		ns, id, tags := iter.Current()
    67  		assert.True(t, opts.namespace.Equal(ns))
    68  
    69  		idStr := id.String()
    70  		result, ok := expected[idStr]
    71  		require.True(t, ok,
    72  			fmt.Sprintf("not expecting ID: %s", idStr))
    73  
    74  		expectedTagsIter := ident.NewTagsIterator(result.series.Tags)
    75  		matcher := ident.NewTagIterMatcher(expectedTagsIter)
    76  		assert.True(t, matcher.Matches(tags),
    77  			fmt.Sprintf("tags not matching for ID: %s", idStr))
    78  
    79  		result.matched = true
    80  	}
    81  	require.NoError(t, iter.Err())
    82  
    83  	var matched, notMatched []string
    84  	for _, elem := range expected {
    85  		if elem.matched {
    86  			matched = append(matched, elem.series.ID.String())
    87  			continue
    88  		}
    89  		notMatched = append(notMatched, elem.series.ID.String())
    90  	}
    91  
    92  	assert.Equal(t, len(expected), compared,
    93  		fmt.Sprintf("matched: %v, not matched: %v", matched, notMatched))
    94  }
    95  
    96  type tagValue string
    97  type tagName string
    98  type aggregateTagValues map[tagValue]struct{}
    99  type aggregateTags map[tagName]aggregateTagValues
   100  type tagValueSeen bool
   101  
   102  type verifyQueryAggregateMetadataResultsOptions struct {
   103  	exhaustive bool
   104  	expected   aggregateTags
   105  }
   106  
   107  func verifyQueryAggregateMetadataResults(
   108  	t *testing.T,
   109  	iter client.AggregatedTagsIterator,
   110  	exhaustive bool,
   111  	opts verifyQueryAggregateMetadataResultsOptions,
   112  ) {
   113  	assert.Equal(t, opts.exhaustive, exhaustive)
   114  
   115  	expected := make(map[tagName]map[tagValue]tagValueSeen, len(opts.expected))
   116  	for name, values := range opts.expected {
   117  		expected[name] = map[tagValue]tagValueSeen{}
   118  		for value := range values {
   119  			expected[name][value] = tagValueSeen(false)
   120  		}
   121  	}
   122  
   123  	for iter.Next() {
   124  		name, values := iter.Current()
   125  
   126  		result, ok := expected[tagName(name.String())]
   127  		require.True(t, ok,
   128  			fmt.Sprintf("not expecting tag: %s", name.String()))
   129  
   130  		for values.Next() {
   131  			value := values.Current()
   132  
   133  			entry, ok := result[tagValue(value.String())]
   134  			require.True(t, ok,
   135  				fmt.Sprintf("not expecting tag value: name=%s, value=%s",
   136  					name.String(), value.String()))
   137  			require.False(t, bool(entry))
   138  
   139  			result[tagValue(value.String())] = tagValueSeen(true)
   140  		}
   141  
   142  		require.NoError(t, values.Err())
   143  	}
   144  	require.NoError(t, iter.Err())
   145  
   146  	var matched, notMatched []string
   147  	for name, values := range expected {
   148  		for value, valueMatched := range values {
   149  			elem := fmt.Sprintf("(tagName=%s, tagValue=%s)", name, value)
   150  			if valueMatched {
   151  				matched = append(matched, elem)
   152  				continue
   153  			}
   154  			notMatched = append(notMatched, elem)
   155  		}
   156  	}
   157  
   158  	assert.Equal(t, 0, len(notMatched),
   159  		fmt.Sprintf("matched: %v, not matched: %v", matched, notMatched))
   160  }